Best JavaScript code snippet using ng-mocks
control_test.js
Source:control_test.js
1// Copyright 2008 The Closure Library Authors. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS-IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14goog.provide('goog.ui.ControlTest');15goog.setTestOnly('goog.ui.ControlTest');16goog.require('goog.a11y.aria');17goog.require('goog.a11y.aria.State');18goog.require('goog.array');19goog.require('goog.dom');20goog.require('goog.dom.TagName');21goog.require('goog.dom.classlist');22goog.require('goog.events');23goog.require('goog.events.BrowserEvent');24goog.require('goog.events.KeyCodes');25goog.require('goog.object');26goog.require('goog.string');27goog.require('goog.style');28goog.require('goog.testing.ExpectedFailures');29goog.require('goog.testing.events');30goog.require('goog.testing.events.Event');31goog.require('goog.testing.jsunit');32goog.require('goog.ui.Component');33goog.require('goog.ui.Control');34goog.require('goog.ui.ControlRenderer');35goog.require('goog.ui.registry');36goog.require('goog.userAgent');37// Disabled due to problems on farm.38var testFocus = false;39var control;40var ALL_EVENTS = goog.object.getValues(goog.ui.Component.EventType);41var events = {};42var expectedFailures;43var sandbox;44var aria = goog.a11y.aria;45var State = goog.a11y.aria.State;46function setUpPage() {47 expectedFailures = new goog.testing.ExpectedFailures();48 sandbox = document.getElementById('sandbox');49}50/**51 * A dummy renderer, for testing purposes.52 * @constructor53 * @extends {goog.ui.ControlRenderer}54 */55function TestRenderer() {56 goog.ui.ControlRenderer.call(this);57}58goog.inherits(TestRenderer, goog.ui.ControlRenderer);59/**60 * Initializes the testcase prior to execution.61 */62function setUp() {63 control = new goog.ui.Control('Hello');64 control.setDispatchTransitionEvents(goog.ui.Component.State.ALL, true);65 goog.events.listen(control, ALL_EVENTS, countEvent);66}67/**68 * Cleans up after executing the testcase.69 */70function tearDown() {71 control.dispose();72 expectedFailures.handleTearDown();73 goog.dom.removeChildren(sandbox);74 resetEventCount();75}76/**77 * Resets the global counter for events dispatched by test objects.78 */79function resetEventCount() {80 goog.object.clear(events);81}82/**83 * Increments the global counter for events of this type.84 * @param {goog.events.Event} e Event to count.85 */86function countEvent(e) {87 var type = e.type;88 var target = e.target;89 if (!events[target]) {90 events[target] = {};91 }92 if (events[target][type]) {93 events[target][type]++;94 } else {95 events[target][type] = 1;96 }97}98/**99 * Returns the number of times test objects dispatched events of the given100 * type since the global counter was last reset.101 * @param {goog.ui.Control} target Event target.102 * @param {string} type Event type.103 * @return {number} Number of events of this type.104 */105function getEventCount(target, type) {106 return events[target] && events[target][type] || 0;107}108/**109 * Returns true if no events were dispatched since the last reset.110 * @return {boolean} Whether no events have been dispatched since the last111 * reset.112 */113function noEventsDispatched() {114 return !events || goog.object.isEmpty(events);115}116/**117 * Returns the number of event listeners created by the control.118 * @param {goog.ui.Control} control Control whose event listers are to be119 * counted.120 * @return {number} Number of event listeners.121 */122function getListenerCount(control) {123 return control.googUiComponentHandler_ ?124 goog.object.getCount(control.getHandler().keys_) : 0;125}126/**127 * Simulates a mousedown event on the given element, including focusing it.128 * @param {Element} element Element on which to simulate mousedown.129 * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button;130 * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}.131 * @return {boolean} Whether the event was allowed to proceed.132 */133function fireMouseDownAndFocus(element, opt_button) {134 var result = goog.testing.events.fireMouseDownEvent(element, opt_button);135 if (result) {136 // Browsers move focus for all buttons, not just the left button.137 element.focus();138 }139 return result;140}141/**142 * @return {boolean} Whether we're on Mac Safari 3.x.143 */144function isMacSafari3() {145 return goog.userAgent.WEBKIT && goog.userAgent.MAC &&146 !goog.userAgent.isVersionOrHigher('527');147}148/**149 * Tests the {@link goog.ui.Control} constructor.150 */151function testConstructor() {152 assertNotNull('Constructed control must not be null', control);153 assertEquals('Content must have expected value', 'Hello',154 control.getContent());155 assertEquals('Renderer must default to the registered renderer',156 goog.ui.registry.getDefaultRenderer(goog.ui.Control),157 control.getRenderer());158 var content = goog.dom.createDom(goog.dom.TagName.DIV, null, 'Hello',159 goog.dom.createDom(goog.dom.TagName.B, null, 'World'));160 var testRenderer = new TestRenderer();161 var fakeDomHelper = {};162 var foo = new goog.ui.Control(content, testRenderer, fakeDomHelper);163 assertNotNull('Constructed object must not be null', foo);164 assertEquals('Content must have expected value', content,165 foo.getContent());166 assertEquals('Renderer must have expected value', testRenderer,167 foo.getRenderer());168 assertEquals('DOM helper must have expected value', fakeDomHelper,169 foo.getDomHelper());170 foo.dispose();171}172/**173 * Tests {@link goog.ui.Control#getHandler}.174 */175function testGetHandler() {176 assertUndefined('Event handler must be undefined before getHandler() ' +177 'is called', control.googUiComponentHandler_);178 var handler = control.getHandler();179 assertNotNull('Event handler must not be null', handler);180 assertEquals('getHandler() must return the same instance if called again',181 handler, control.getHandler());182}183/**184 * Tests {@link goog.ui.Control#isHandleMouseEvents}.185 */186function testIsHandleMouseEvents() {187 assertTrue('Controls must handle their own mouse events by default',188 control.isHandleMouseEvents());189}190/**191 * Tests {@link goog.ui.Control#setHandleMouseEvents}.192 */193function testSetHandleMouseEvents() {194 assertTrue('Control must handle its own mouse events by default',195 control.isHandleMouseEvents());196 control.setHandleMouseEvents(false);197 assertFalse('Control must no longer handle its own mouse events',198 control.isHandleMouseEvents());199 control.setHandleMouseEvents(true);200 assertTrue('Control must once again handle its own mouse events',201 control.isHandleMouseEvents());202 control.render(sandbox);203 assertTrue('Rendered control must handle its own mouse events',204 control.isHandleMouseEvents());205 control.setHandleMouseEvents(false);206 assertFalse('Rendered control must no longer handle its own mouse events',207 control.isHandleMouseEvents());208 control.setHandleMouseEvents(true);209 assertTrue('Rendered control must once again handle its own mouse events',210 control.isHandleMouseEvents());211}212/**213 * Tests {@link goog.ui.Control#getKeyEventTarget}.214 */215function testGetKeyEventTarget() {216 assertNull('Key event target of control without DOM must be null',217 control.getKeyEventTarget());218 control.createDom();219 assertEquals('Key event target of control with DOM must be its element',220 control.getElement(), control.getKeyEventTarget());221}222/**223 * Tests {@link goog.ui.Control#getKeyHandler}.224 */225function testGetKeyHandler() {226 assertUndefined('Key handler must be undefined before getKeyHandler() ' +227 'is called', control.keyHandler_);228 var keyHandler = control.getKeyHandler();229 assertNotNull('Key handler must not be null', keyHandler);230 assertEquals('getKeyHandler() must return the same instance if called ' +231 'again', keyHandler, control.getKeyHandler());232}233/**234 * Tests {@link goog.ui.Control#getRenderer}.235 */236function testGetRenderer() {237 assertEquals('Renderer must be the default registered renderer',238 goog.ui.registry.getDefaultRenderer(goog.ui.Control),239 control.getRenderer());240}241/**242 * Tests {@link goog.ui.Control#setRenderer}.243 */244function testSetRenderer() {245 control.createDom();246 assertNotNull('Control must have a DOM', control.getElement());247 assertFalse('Control must not be in the document',248 control.isInDocument());249 assertEquals('Renderer must be the default registered renderer',250 goog.ui.registry.getDefaultRenderer(goog.ui.Control),251 control.getRenderer());252 var testRenderer = new TestRenderer();253 control.setRenderer(testRenderer);254 assertNull('Control must not have a DOM after its renderer is reset',255 control.getElement());256 assertFalse('Control still must not be in the document',257 control.isInDocument());258 assertEquals('Renderer must have expected value', testRenderer,259 control.getRenderer());260 control.render(sandbox);261 assertTrue('Control must be in the document', control.isInDocument());262 assertThrows('Resetting the renderer after the control has entered ' +263 'the document must throw error',264 function() {265 control.setRenderer({});266 });267}268/**269 * Tests {@link goog.ui.Control#getExtraClassNames}.270 */271function testGetExtraClassNames() {272 assertNull('Control must not have any extra class names by default',273 control.getExtraClassNames());274}275/**276 * Tests {@link goog.ui.Control#addExtraClassName} and277 * {@link goog.ui.Control#removeExtraClassName}.278 */279function testAddRemoveClassName() {280 assertNull('Control must not have any extra class names by default',281 control.getExtraClassNames());282 control.addClassName('foo');283 assertArrayEquals('Control must have expected extra class names',284 ['foo'], control.getExtraClassNames());285 assertNull('Control must not have a DOM', control.getElement());286 control.createDom();287 assertSameElements('Control\'s element must have expected class names',288 ['goog-control', 'foo'],289 goog.dom.classlist.get(control.getElement()));290 control.addClassName('bar');291 assertArrayEquals('Control must have expected extra class names',292 ['foo', 'bar'], control.getExtraClassNames());293 assertSameElements('Control\'s element must have expected class names',294 ['goog-control', 'foo', 'bar'],295 goog.dom.classlist.get(control.getElement()));296 control.addClassName('bar');297 assertArrayEquals('Adding the same class name again must be a no-op',298 ['foo', 'bar'], control.getExtraClassNames());299 assertSameElements('Adding the same class name again must be a no-op',300 ['goog-control', 'foo', 'bar'],301 goog.dom.classlist.get(control.getElement()));302 control.addClassName(null);303 assertArrayEquals('Adding null class name must be a no-op',304 ['foo', 'bar'], control.getExtraClassNames());305 assertSameElements('Adding null class name must be a no-op',306 ['goog-control', 'foo', 'bar'],307 goog.dom.classlist.get(control.getElement()));308 control.removeClassName(null);309 assertArrayEquals('Removing null class name must be a no-op',310 ['foo', 'bar'], control.getExtraClassNames());311 assertSameElements('Removing null class name must be a no-op',312 ['goog-control', 'foo', 'bar'],313 goog.dom.classlist.get(control.getElement()));314 control.removeClassName('foo');315 assertArrayEquals('Control must have expected extra class names',316 ['bar'], control.getExtraClassNames());317 assertSameElements('Control\'s element must have expected class names',318 ['goog-control', 'bar'],319 goog.dom.classlist.get(control.getElement()));320 control.removeClassName('bar');321 assertNull('Control must not have any extra class names',322 control.getExtraClassNames());323 assertSameElements('Control\'s element must have expected class names',324 ['goog-control'],325 goog.dom.classlist.get(control.getElement()));326}327/**328 * Tests {@link goog.ui.Control#enableClassName}.329 */330function testEnableClassName() {331 assertNull('Control must not have any extra class names by default',332 control.getExtraClassNames());333 control.enableClassName('foo', true);334 assertArrayEquals('Control must have expected extra class names',335 ['foo'], control.getExtraClassNames());336 control.enableClassName('bar', true);337 assertArrayEquals('Control must have expected extra class names',338 ['foo', 'bar'], control.getExtraClassNames());339 control.enableClassName('bar', true);340 assertArrayEquals('Enabling the same class name again must be a no-op',341 ['foo', 'bar'], control.getExtraClassNames());342 control.enableClassName(null);343 assertArrayEquals('Enabling null class name must be a no-op',344 ['foo', 'bar'], control.getExtraClassNames());345 control.enableClassName('foo', false);346 assertArrayEquals('Control must have expected extra class names',347 ['bar'], control.getExtraClassNames());348 control.enableClassName('bar', false);349 assertNull('Control must not have any extra class names',350 control.getExtraClassNames());351}352/**353 * Tests {@link goog.ui.Control#createDom}.354 */355function testCreateDom() {356 assertNull('Control must not have a DOM by default',357 control.getElement());358 assertFalse('Control must not allow text selection by default',359 control.isAllowTextSelection());360 assertTrue('Control must be visible by default', control.isVisible());361 control.createDom();362 assertNotNull('Control must have a DOM', control.getElement());363 assertTrue('Control\'s element must be unselectable',364 goog.style.isUnselectable(control.getElement()));365 assertTrue('Control\'s element must be visible',366 control.getElement().style.display != 'none');367 control.setAllowTextSelection(true);368 control.createDom();369 assertFalse('Control\'s element must be selectable',370 goog.style.isUnselectable(control.getElement()));371 control.setVisible(false);372 control.createDom();373 assertTrue('Control\'s element must be hidden',374 control.getElement().style.display == 'none');375}376/**377 * Tests {@link goog.ui.Control#getContentElement}.378 */379function testGetContentElement() {380 assertNull('Unrendered control must not have a content element',381 control.getContentElement());382 control.createDom();383 assertEquals('Control\'s content element must equal its root element',384 control.getElement(), control.getContentElement());385}386/**387 * Tests {@link goog.ui.Control#canDecorate}.388 */389function testCanDecorate() {390 assertTrue(control.canDecorate(goog.dom.createElement(goog.dom.TagName.DIV)));391}392/**393 * Tests {@link goog.ui.Control#decorateInternal}.394 */395function testDecorateInternal() {396 sandbox.innerHTML = '<div id="foo">Hello, <b>World</b>!</div>';397 var foo = goog.dom.getElement('foo');398 control.decorate(foo);399 assertEquals('Decorated control\'s element must have expected value',400 foo, control.getElement());401 assertTrue('Element must be unselectable',402 goog.style.isUnselectable(control.getElement()));403 assertTrue('Element must be visible',404 control.getElement().style.display != 'none');405}406/**407 * Tests {@link goog.ui.Control#decorateInternal} with a control that408 * allows text selection.409 */410function testDecorateInternalForSelectableControl() {411 sandbox.innerHTML = '<div id="foo">Hello, <b>World</b>!</div>';412 var foo = goog.dom.getElement('foo');413 control.setAllowTextSelection(true);414 control.decorate(foo);415 assertEquals('Decorated control\'s element must have expected value',416 foo, control.getElement());417 assertFalse('Element must be selectable',418 goog.style.isUnselectable(control.getElement()));419 assertTrue('Control must be visible', control.isVisible());420}421/**422 * Tests {@link goog.ui.Control#decorateInternal} with a hidden element.423 */424function testDecorateInternalForHiddenElement() {425 sandbox.innerHTML = '<div id="foo" style="display:none">Hello!</div>';426 var foo = goog.dom.getElement('foo');427 control.decorate(foo);428 assertEquals('Decorated control\'s element must have expected value',429 foo, control.getElement());430 assertTrue('Element must be unselectable',431 goog.style.isUnselectable(control.getElement()));432 assertFalse('Control must be hidden', control.isVisible());433}434/**435 * Tests {@link goog.ui.Control#enterDocument}.436 */437function testEnterDocument() {438 control.render(sandbox);439 assertTrue('Control must be in the document', control.isInDocument());440 if (goog.userAgent.IE) {441 assertEquals('Control must have 5 mouse & 3 key event listeners on IE',442 8, getListenerCount(control));443 } else {444 assertEquals('Control must have 4 mouse and 3 key event listeners', 7,445 getListenerCount(control));446 }447 assertEquals('Control\'s key event handler must be attached to its ' +448 'key event target', control.getKeyEventTarget(),449 control.getKeyHandler().element_);450}451/**452 * Tests {@link goog.ui.Control#enterDocument} for a control that doesn't453 * handle mouse events.454 */455function testEnterDocumentForControlWithoutMouseHandling() {456 control.setHandleMouseEvents(false);457 control.render(sandbox);458 assertTrue('Control must be in the document', control.isInDocument());459 assertEquals('Control must have 3 key event listeners', 3,460 getListenerCount(control));461 assertEquals('Control\'s key event handler must be attached to its ' +462 'key event target', control.getKeyEventTarget(),463 control.getKeyHandler().element_);464}465/**466 * Tests {@link goog.ui.Control#enterDocument} for a control that isn't467 * focusable.468 */469function testEnterDocumentForNonFocusableControl() {470 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);471 control.render(sandbox);472 assertTrue('Control must be in the document', control.isInDocument());473 if (goog.userAgent.IE) {474 assertEquals('Control must have 5 mouse event listeners on IE', 5,475 getListenerCount(control));476 } else {477 assertEquals('Control must have 4 mouse event listeners', 4,478 getListenerCount(control));479 }480 assertUndefined('Control must not have a key event handler',481 control.keyHandler_);482}483/**484 * Tests {@link goog.ui.Control#enterDocument} for a control that doesn't485 * need to do any event handling.486 */487function testEnterDocumentForControlWithoutEventHandlers() {488 control.setHandleMouseEvents(false);489 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);490 control.render(sandbox);491 assertTrue('Control must be in the document', control.isInDocument());492 assertEquals('Control must have 0 event listeners', 0,493 getListenerCount(control));494 assertUndefined('Control must not have an event handler',495 control.googUiComponentHandler_);496 assertUndefined('Control must not have a key event handler',497 control.keyHandler_);498}499/**500 * Tests {@link goog.ui.Control#exitDocument}.501 */502function testExitDocument() {503 control.render(sandbox);504 assertTrue('Control must be in the document', control.isInDocument());505 if (goog.userAgent.IE) {506 assertEquals('Control must have 5 mouse & 3 key event listeners on IE',507 8, getListenerCount(control));508 } else {509 assertEquals('Control must have 4 mouse and 3 key event listeners', 7,510 getListenerCount(control));511 }512 assertEquals('Control\'s key event handler must be attached to its ' +513 'key event target', control.getKeyEventTarget(),514 control.getKeyHandler().element_);515 // Expected to fail on Mac Safari prior to version 527.516 expectedFailures.expectFailureFor(isMacSafari3());517 try {518 assertTrue('Control\'s element must support keyboard focus',519 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));520 } catch (e) {521 expectedFailures.handleException(e);522 }523 control.exitDocument();524 assertFalse('Control must no longer be in the document',525 control.isInDocument());526 assertEquals('Control must have no event listeners', 0,527 getListenerCount(control));528 assertNull('Control\'s key event handler must be unattached',529 control.getKeyHandler().element_);530 assertFalse('Control\'s element must no longer support keyboard focus',531 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));532}533/**534 * Tests {@link goog.ui.Control#dispose}.535 */536function testDispose() {537 control.render(sandbox);538 var handler = control.getHandler();539 var keyHandler = control.getKeyHandler();540 control.dispose();541 assertFalse('Control must no longer be in the document',542 control.isInDocument());543 assertTrue('Control must have been disposed of', control.isDisposed());544 assertUndefined('Renderer must have been deleted', control.getRenderer());545 assertNull('Content must be nulled out', control.getContent());546 assertTrue('Event handler must have been disposed of',547 handler.isDisposed());548 assertUndefined('Event handler must have been deleted',549 control.googUiComponentHandler_);550 assertTrue('Key handler must have been disposed of',551 keyHandler.isDisposed());552 assertUndefined('Key handler must have been deleted',553 control.keyHandler_);554 assertNull('Extra class names must have been nulled out',555 control.getExtraClassNames());556}557/**558 * Tests {@link goog.ui.Control#getContent}.559 */560function testGetContent() {561 assertNull('Empty control must have null content',562 (new goog.ui.Control(null)).getContent());563 assertEquals('Control must have expected content', 'Hello',564 control.getContent());565 control.render(sandbox);566 assertEquals('Control must have expected content after rendering',567 'Hello', control.getContent());568}569/**570 * Tests {@link goog.ui.Control#getContent}.571 */572function testGetContentForDecoratedControl() {573 sandbox.innerHTML =574 '<div id="empty"></div>\n' +575 '<div id="text">Hello, world!</div>\n' +576 '<div id="element"><span>Foo</span></div>\n' +577 '<div id="nodelist">Hello, <b>world</b>!</div>\n';578 var empty = new goog.ui.Control(null);579 empty.decorate(goog.dom.getElement('empty'));580 assertNull('Content of control decorating empty DIV must be null',581 empty.getContent());582 empty.dispose();583 var text = new goog.ui.Control(null);584 text.decorate(goog.dom.getElement('text'));585 assertEquals('Content of control decorating DIV with text contents ' +586 'must be as expected', 'Hello, world!', text.getContent().nodeValue);587 text.dispose();588 var element = new goog.ui.Control(null);589 element.decorate(goog.dom.getElement('element'));590 assertEquals('Content of control decorating DIV with element child ' +591 'must be as expected', goog.dom.getElement('element').firstChild,592 element.getContent());593 element.dispose();594 var nodelist = new goog.ui.Control(null);595 nodelist.decorate(goog.dom.getElement('nodelist'));596 assertSameElements('Content of control decorating DIV with mixed ' +597 'contents must be as expected',598 goog.dom.getElement('nodelist').childNodes, nodelist.getContent());599 nodelist.dispose();600}601/**602 * Tests {@link goog.ui.Control#setAriaLabel}.603 */604function testSetAriaLabel_render() {605 assertNull('Controls must not have any aria label by default',606 control.getAriaLabel());607 control.setAriaLabel('label');608 assertEquals('Control must have aria label', 'label', control.getAriaLabel());609 control.render(sandbox);610 var elem = control.getElementStrict();611 assertEquals(612 'Element must have control\'s aria label after rendering',613 'label',614 goog.a11y.aria.getLabel(elem));615 control.setAriaLabel('new label');616 assertEquals('Element must have the new aria label',617 'new label',618 goog.a11y.aria.getLabel(elem));619}620/**621 * Tests {@link goog.ui.Control#setAriaLabel}.622 */623function testSetAriaLabel_decorate() {624 assertNull('Controls must not have any aria label by default',625 control.getAriaLabel());626 control.setAriaLabel('label');627 assertEquals('Control must have aria label', 'label', control.getAriaLabel());628 sandbox.innerHTML = '<div id="nodelist" role="button">' +629 'Hello, <b>world</b>!</div>';630 control.decorate(goog.dom.getElement('nodelist'));631 var elem = control.getElementStrict();632 assertEquals(633 'Element must have control\'s aria label after rendering',634 'label',635 goog.a11y.aria.getLabel(elem));636 assertEquals(637 'Element must have the correct role',638 'button',639 elem.getAttribute('role'));640 control.setAriaLabel('new label');641 assertEquals('Element must have the new aria label',642 'new label',643 goog.a11y.aria.getLabel(elem));644}645/**646 * Tests {@link goog.ui.Control#setContent}.647 */648function testSetContent() {649 control.setContent('Bye');650 assertEquals('Unrendered control control must have expected contents',651 'Bye', control.getContent());652 assertNull('No DOM must be created by setContent', control.getElement());653 control.createDom();654 assertEquals('Rendered control\'s DOM must have expected contents',655 'Bye', control.getElement().innerHTML);656 control.setContent(null);657 assertNull('Rendered control must have expected contents',658 control.getContent());659 assertEquals('Rendered control\'s DOM must have expected contents',660 '', control.getElement().innerHTML);661 control.setContent([goog.dom.createDom(goog.dom.TagName.DIV, null,662 goog.dom.createDom(goog.dom.TagName.SPAN, null, 'Hello')), 'World']);663 assertHTMLEquals('Control\'s DOM must be updated',664 '<div><span>Hello</span></div>World', control.getElement().innerHTML);665}666/**667 * Tests {@link goog.ui.Control#setContentInternal}.668 */669function testSetContentInternal() {670 control.render(sandbox);671 assertEquals('Control must have expected content after rendering',672 'Hello', control.getContent());673 control.setContentInternal('Bye');674 assertEquals('Control must have expected contents',675 'Bye', control.getContent());676 assertEquals('Control\'s DOM must be unchanged', 'Hello',677 control.getElement().innerHTML);678}679/**680 * Tests {@link goog.ui.Control#getCaption}.681 */682function testGetCaption() {683 assertEquals('Empty control\'s caption must be empty string', '',684 (new goog.ui.Control(null)).getCaption());685 assertEquals('Caption must have expected value', 'Hello',686 control.getCaption());687 sandbox.innerHTML = '<div id="nodelist">Hello, <b>world</b>!</div>';688 control.decorate(goog.dom.getElement('nodelist'));689 assertEquals('Caption must have expected value', 'Hello, world!',690 control.getCaption());691 var arrayContent = goog.array.clone(goog.dom.htmlToDocumentFragment(692 ' <b> foo</b><i> bar</i> ').childNodes);693 control.setContent(arrayContent);694 assertEquals('whitespaces must be normalized in the caption',695 'foo bar', control.getCaption());696 control.setContent('\xa0foo');697 assertEquals('indenting spaces must be kept', '\xa0foo',698 control.getCaption());699}700/**701 * Tests {@link goog.ui.Control#setCaption}.702 */703function testSetCaption() {704 control.setCaption('Hello, world!');705 assertEquals('Control must have a string caption "Hello, world!"',706 'Hello, world!', control.getCaption());707}708/**709 * Tests {@link goog.ui.Control#setRightToLeft}.710 */711function testSetRightToLeft() {712 control.createDom();713 assertFalse('Control\'s element must not have right-to-left class',714 goog.dom.classlist.contains(control.getElement(),715 'goog-control-rtl'));716 control.setRightToLeft(true);717 assertTrue('Control\'s element must have right-to-left class',718 goog.dom.classlist.contains(control.getElement(),719 'goog-control-rtl'));720 control.render(sandbox);721 assertThrows('Changing the render direction of a control already in ' +722 'the document is an error',723 function() {724 control.setRightToLeft(false);725 });726}727/**728 * Tests {@link goog.ui.Control#isAllowTextSelection}.729 */730function testIsAllowTextSelection() {731 assertFalse('Controls must not allow text selection by default',732 control.isAllowTextSelection());733}734/**735 * Tests {@link goog.ui.Control#setAllowTextSelection}.736 */737function testSetAllowTextSelection() {738 assertFalse('Controls must not allow text selection by default',739 control.isAllowTextSelection());740 control.setAllowTextSelection(true);741 assertTrue('Control must allow text selection',742 control.isAllowTextSelection());743 control.setAllowTextSelection(false);744 assertFalse('Control must no longer allow text selection',745 control.isAllowTextSelection());746 control.render(sandbox);747 assertFalse('Control must not allow text selection even after rendered',748 control.isAllowTextSelection());749 control.setAllowTextSelection(true);750 assertTrue('Control must once again allow text selection',751 control.isAllowTextSelection());752}753/**754 * Tests {@link goog.ui.Control#isVisible}.755 */756function testIsVisible() {757 assertTrue('Controls must be visible by default', control.isVisible());758}759/**760 * Tests {@link goog.ui.Control#setVisible} before it is rendered.761 */762function testSetVisible() {763 assertFalse('setVisible(true) must return false if already visible',764 control.setVisible(true));765 assertTrue('No events must have been dispatched', noEventsDispatched());766 assertTrue('setVisible(false) must return true if previously visible',767 control.setVisible(false));768 assertEquals('One HIDE event must have been dispatched',769 1, getEventCount(control, goog.ui.Component.EventType.HIDE));770 assertFalse('Control must no longer be visible', control.isVisible());771 assertTrue('setVisible(true) must return true if previously hidden',772 control.setVisible(true));773 assertEquals('One SHOW event must have been dispatched',774 1, getEventCount(control, goog.ui.Component.EventType.SHOW));775 assertTrue('Control must be visible', control.isVisible());776}777/**778 * Tests {@link goog.ui.Control#setVisible} after it is rendered.779 */780function testSetVisibleForRenderedControl() {781 control.render(sandbox);782 assertTrue('No events must have been dispatched during rendering',783 noEventsDispatched());784 assertFalse('setVisible(true) must return false if already visible',785 control.setVisible(true));786 assertTrue('No events must have been dispatched', noEventsDispatched());787 assertTrue('Control\'s element must be visible',788 control.getElement().style.display != 'none');789 assertTrue('setVisible(false) must return true if previously visible',790 control.setVisible(false));791 assertEquals('One HIDE event must have been dispatched',792 1, getEventCount(control, goog.ui.Component.EventType.HIDE));793 assertFalse('Control must no longer be visible', control.isVisible());794 assertTrue('Control\'s element must be hidden',795 control.getElement().style.display == 'none');796 assertTrue('setVisible(true) must return true if previously hidden',797 control.setVisible(true));798 assertEquals('One SHOW event must have been dispatched',799 1, getEventCount(control, goog.ui.Component.EventType.SHOW));800 assertTrue('Control must be visible', control.isVisible());801 assertTrue('Control\'s element must be visible',802 control.getElement().style.display != 'none');803}804/**805 * Tests {@link goog.ui.Control#setVisible} for disabled non-focusable806 * controls.807 */808function testSetVisibleForDisabledNonFocusableControl() {809 // Hidden, disabled, non-focusable control becoming visible.810 control.setEnabled(false);811 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);812 control.render(sandbox);813 assertTrue('Control must be visible', control.isVisible());814 assertFalse('Control must not have a tab index',815 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));816 // Visible, disabled, non-focusable control becoming hidden.817 control.getKeyEventTarget().focus();818 assertEquals('Control must not have dispatched FOCUS', 0,819 getEventCount(control, goog.ui.Component.EventType.FOCUS));820 assertFalse('Control must not have keyboard focus', control.isFocused());821 control.setVisible(false);822 assertFalse('Control must be hidden', control.isVisible());823 assertFalse('Control must not have a tab index',824 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));825 assertEquals('Control must have dispatched HIDE', 1,826 getEventCount(control, goog.ui.Component.EventType.HIDE));827 assertEquals('Control must not have dispatched BLUR', 0,828 getEventCount(control, goog.ui.Component.EventType.BLUR));829}830/**831 * Tests {@link goog.ui.Control#setVisible} for disabled focusable controls.832 */833function testSetVisibleForDisabledFocusableControl() {834 // Hidden, disabled, focusable control becoming visible.835 control.setEnabled(false);836 control.setSupportedState(goog.ui.Component.State.FOCUSED, true);837 control.render(sandbox);838 assertTrue('Control must be visible', control.isVisible());839 assertFalse('Control must not have a tab index',840 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));841 // Visible, disabled, focusable control becoming hidden.842 control.getKeyEventTarget().focus();843 assertEquals('Control must not have dispatched FOCUS', 0,844 getEventCount(control, goog.ui.Component.EventType.FOCUS));845 assertFalse('Control must not have keyboard focus', control.isFocused());846 control.setVisible(false);847 assertFalse('Control must be hidden', control.isVisible());848 assertFalse('Control must not have a tab index',849 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));850 assertEquals('Control must have dispatched HIDE', 1,851 getEventCount(control, goog.ui.Component.EventType.HIDE));852 assertEquals('Control must not have dispatched BLUR', 0,853 getEventCount(control, goog.ui.Component.EventType.BLUR));854}855/**856 * Tests {@link goog.ui.Control#setVisible} for enabled non-focusable857 * controls.858 */859function testSetVisibleForEnabledNonFocusableControl() {860 // Hidden, enabled, non-focusable control becoming visible.861 control.setEnabled(true);862 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);863 control.render(sandbox);864 assertTrue('Control must be visible', control.isVisible());865 assertFalse('Control must not have a tab index',866 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));867 if (testFocus) {868 // Visible, enabled, non-focusable control becoming hidden.869 control.getKeyEventTarget().focus();870 assertEquals('Control must not have dispatched FOCUS', 0,871 getEventCount(control, goog.ui.Component.EventType.FOCUS));872 assertFalse('Control must not have keyboard focus',873 control.isFocused());874 control.setVisible(false);875 assertFalse('Control must be hidden', control.isVisible());876 assertFalse('Control must not have a tab index',877 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));878 assertEquals('Control must have dispatched HIDE', 1,879 getEventCount(control, goog.ui.Component.EventType.HIDE));880 assertEquals('Control must not have dispatched BLUR', 0,881 getEventCount(control, goog.ui.Component.EventType.BLUR));882 }883}884/**885 * Tests {@link goog.ui.Control#setVisible} for enabled focusable controls.886 */887function testSetVisibleForEnabledFocusableControl() {888 // Hidden, enabled, focusable control becoming visible.889 control.setEnabled(true);890 control.setSupportedState(goog.ui.Component.State.FOCUSED, true);891 control.render(sandbox);892 assertTrue('Control must be visible', control.isVisible());893 if (testFocus) {894 // Expected to fail on Mac Safari prior to version 527.895 expectedFailures.expectFailureFor(isMacSafari3());896 try {897 // Mac Safari currently doesn't support tabIndex on arbitrary898 // elements.899 assertTrue('Control must have a tab index',900 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));901 } catch (e) {902 expectedFailures.handleException(e);903 }904 // Visible, enabled, focusable control becoming hidden.905 control.getKeyEventTarget().focus();906 // Expected to fail on IE.907 expectedFailures.expectFailureFor(goog.userAgent.IE);908 try {909 // IE dispatches focus and blur events asynchronously!910 assertEquals('Control must have dispatched FOCUS', 1,911 getEventCount(control, goog.ui.Component.EventType.FOCUS));912 assertTrue('Control must have keyboard focus', control.isFocused());913 } catch (e) {914 expectedFailures.handleException(e);915 }916 control.setVisible(false);917 assertFalse('Control must be hidden', control.isVisible());918 assertFalse('Control must not have a tab index',919 goog.dom.isFocusableTabIndex(control.getKeyEventTarget()));920 assertEquals('Control must have dispatched HIDE', 1,921 getEventCount(control, goog.ui.Component.EventType.HIDE));922 // Expected to fail on IE.923 expectedFailures.expectFailureFor(goog.userAgent.IE);924 try {925 // IE dispatches focus and blur events asynchronously!926 assertEquals('Control must have dispatched BLUR', 1,927 getEventCount(control, goog.ui.Component.EventType.BLUR));928 assertFalse('Control must no longer have keyboard focus',929 control.isFocused());930 } catch (e) {931 expectedFailures.handleException(e);932 }933 }934}935/**936 * Tests {@link goog.ui.Control#isEnabled}.937 */938function testIsEnabled() {939 assertTrue('Controls must be enabled by default', control.isEnabled());940}941/**942 * Tests {@link goog.ui.Control#setEnabled}.943 */944function testSetEnabled() {945 control.render(sandbox);946 control.setHighlighted(true);947 control.setActive(true);948 control.getKeyEventTarget().focus();949 resetEventCount();950 control.setEnabled(true);951 assertTrue('No events must have been dispatched', noEventsDispatched());952 assertTrue('Control must be enabled', control.isEnabled());953 assertTrue('Control must be highlighted', control.isHighlighted());954 assertTrue('Control must be active', control.isActive());955 var elem = control.getElementStrict();956 assertTrue('Control element must not have aria-disabled',957 goog.string.isEmptyOrWhitespace(aria.getState(elem, State.DISABLED)));958 assertEquals('Control element must have a tabIndex of 0', 0,959 goog.string.toNumber(elem.getAttribute('tabIndex') || ''));960 if (testFocus) {961 // Expected to fail on IE and Mac Safari 3. IE calls focus handlers962 // asynchronously, and Mac Safari 3 doesn't support keyboard focus.963 expectedFailures.expectFailureFor(goog.userAgent.IE);964 expectedFailures.expectFailureFor(isMacSafari3());965 try {966 assertTrue('Control must be focused', control.isFocused());967 } catch (e) {968 expectedFailures.handleException(e);969 }970 }971 resetEventCount();972 control.setEnabled(false);973 assertEquals('One DISABLE event must have been dispatched', 1,974 getEventCount(control, goog.ui.Component.EventType.DISABLE));975 assertFalse('Control must be disabled', control.isEnabled());976 assertFalse('Control must not be highlighted', control.isHighlighted());977 assertFalse('Control must not be active', control.isActive());978 assertFalse('Control must not be focused', control.isFocused());979 assertEquals('Control element must have aria-disabled true', 'true',980 aria.getState(control.getElementStrict(), State.DISABLED));981 assertNull('Control element must not have a tabIndex',982 control.getElement().getAttribute('tabIndex'));983 control.setEnabled(true);984 control.exitDocument();985 var cssClass = goog.getCssName(goog.ui.ControlRenderer.CSS_CLASS, 'disabled');986 var element = goog.dom.createDom(goog.dom.TagName.DIV, {tabIndex: 0});987 element.className = cssClass;988 goog.dom.appendChild(sandbox, element);989 control.decorate(element);990 assertEquals('Control element must have aria-disabled true', 'true',991 aria.getState(control.getElementStrict(), State.DISABLED));992 assertNull('Control element must not have a tabIndex',993 control.getElement().getAttribute('tabIndex'));994 control.setEnabled(true);995 elem = control.getElementStrict();996 assertEquals('Control element must have aria-disabled false', 'false',997 aria.getState(elem, State.DISABLED));998 assertEquals('Control element must have tabIndex 0', 0,999 goog.string.toNumber(elem.getAttribute('tabIndex') || ''));1000}1001/**1002 * Tests {@link goog.ui.Control#setState} when using1003 * goog.ui.Component.State.DISABLED.1004 */1005function testSetStateWithDisabled() {1006 control.render(sandbox);1007 control.setHighlighted(true);1008 control.setActive(true);1009 control.getKeyEventTarget().focus();1010 resetEventCount();1011 control.setState(goog.ui.Component.State.DISABLED, false);1012 assertTrue('No events must have been dispatched', noEventsDispatched());1013 assertTrue('Control must be enabled', control.isEnabled());1014 assertTrue('Control must be highlighted', control.isHighlighted());1015 assertTrue('Control must be active', control.isActive());1016 assertTrue('Control element must not have aria-disabled',1017 goog.string.isEmptyOrWhitespace(1018 aria.getState(control.getElementStrict(), State.DISABLED)));1019 assertEquals('Control element must have a tabIndex of 0', 0,1020 goog.string.toNumber(1021 control.getElement().getAttribute('tabIndex') || ''));1022 if (testFocus) {1023 // Expected to fail on IE and Mac Safari 3. IE calls focus handlers1024 // asynchronously, and Mac Safari 3 doesn't support keyboard focus.1025 expectedFailures.expectFailureFor(goog.userAgent.IE);1026 expectedFailures.expectFailureFor(isMacSafari3());1027 try {1028 assertTrue('Control must be focused', control.isFocused());1029 } catch (e) {1030 expectedFailures.handleException(e);1031 }1032 }1033 resetEventCount();1034 control.setState(goog.ui.Component.State.DISABLED, true);1035 assertEquals('One DISABLE event must have been dispatched', 1,1036 getEventCount(control, goog.ui.Component.EventType.DISABLE));1037 assertFalse('Control must be disabled', control.isEnabled());1038 assertFalse('Control must not be highlighted', control.isHighlighted());1039 assertFalse('Control must not be active', control.isActive());1040 assertFalse('Control must not be focused', control.isFocused());1041 assertEquals('Control element must have aria-disabled true', 'true',1042 aria.getState(control.getElementStrict(), State.DISABLED));1043 assertNull('Control element must not have a tabIndex',1044 control.getElement().getAttribute('tabIndex'));1045 control.setState(goog.ui.Component.State.DISABLED, false);1046 control.exitDocument();1047 var cssClass = goog.getCssName(goog.ui.ControlRenderer.CSS_CLASS, 'disabled');1048 var element = goog.dom.createDom(goog.dom.TagName.DIV, {tabIndex: 0});1049 element.className = cssClass;1050 goog.dom.appendChild(sandbox, element);1051 control.decorate(element);1052 assertEquals('Control element must have aria-disabled true', 'true',1053 aria.getState(control.getElementStrict(), State.DISABLED));1054 assertNull('Control element must not have a tabIndex',1055 control.getElement().getAttribute('tabIndex'));1056 control.setState(goog.ui.Component.State.DISABLED, false);1057 elem = control.getElementStrict();1058 assertEquals('Control element must have aria-disabled false', 'false',1059 aria.getState(elem, State.DISABLED));1060 assertEquals('Control element must have tabIndex 0', 0,1061 goog.string.toNumber(elem.getAttribute('tabIndex') || ''));1062}1063/**1064 * Tests {@link goog.ui.Control#setEnabled} when the control has a parent.1065 */1066function testSetEnabledWithParent() {1067 var child = new goog.ui.Control(null);1068 child.setDispatchTransitionEvents(goog.ui.Component.State.ALL, true);1069 control.addChild(child, true /* opt_render */);1070 control.setEnabled(false);1071 resetEventCount();1072 assertFalse('Parent must be disabled', control.isEnabled());1073 assertTrue('Child must be enabled', child.isEnabled());1074 child.setEnabled(false);1075 assertTrue('No events must have been dispatched when child is disabled',1076 noEventsDispatched());1077 assertTrue('Child must still be enabled', child.isEnabled());1078 resetEventCount();1079 control.setEnabled(true);1080 assertEquals('One ENABLE event must have been dispatched by the parent',1081 1, getEventCount(control, goog.ui.Component.EventType.ENABLE));1082 assertTrue('Parent must be enabled', control.isEnabled());1083 assertTrue('Child must still be enabled', child.isEnabled());1084 resetEventCount();1085 child.setEnabled(false);1086 assertEquals('One DISABLE event must have been dispatched by the child',1087 1, getEventCount(child, goog.ui.Component.EventType.DISABLE));1088 assertTrue('Parent must still be enabled', control.isEnabled());1089 assertFalse('Child must now be disabled', child.isEnabled());1090 resetEventCount();1091 control.setEnabled(false);1092 assertEquals('One DISABLE event must have been dispatched by the parent',1093 1, getEventCount(control, goog.ui.Component.EventType.DISABLE));1094 assertFalse('Parent must now be disabled', control.isEnabled());1095 assertFalse('Child must still be disabled', child.isEnabled());1096 child.dispose();1097}1098/**1099 * Tests {@link goog.ui.Control#isHighlighted}.1100 */1101function testIsHighlighted() {1102 assertFalse('Controls must not be highlighted by default',1103 control.isHighlighted());1104}1105/**1106 * Tests {@link goog.ui.Control#setHighlighted}.1107 */1108function testSetHighlighted() {1109 control.setSupportedState(goog.ui.Component.State.HOVER, false);1110 control.setHighlighted(true);1111 assertFalse('Control must not be highlighted, because it isn\'t ' +1112 'highlightable', control.isHighlighted());1113 assertTrue('Control must not have dispatched any events',1114 noEventsDispatched());1115 control.setSupportedState(goog.ui.Component.State.HOVER, true);1116 control.setHighlighted(true);1117 assertTrue('Control must be highlighted', control.isHighlighted());1118 assertEquals('Control must have dispatched a HIGHLIGHT event', 1,1119 getEventCount(control, goog.ui.Component.EventType.HIGHLIGHT));1120 control.setHighlighted(true);1121 assertTrue('Control must still be highlighted', control.isHighlighted());1122 assertEquals('Control must not dispatch more HIGHLIGHT events', 1,1123 getEventCount(control, goog.ui.Component.EventType.HIGHLIGHT));1124 control.setHighlighted(false);1125 assertFalse('Control must not be highlighted', control.isHighlighted());1126 assertEquals('Control must have dispatched an UNHIGHLIGHT event', 1,1127 getEventCount(control, goog.ui.Component.EventType.UNHIGHLIGHT));1128 control.setEnabled(false);1129 assertFalse('Control must be disabled', control.isEnabled());1130 control.setHighlighted(true);1131 assertTrue('Control must be highlighted, even when disabled',1132 control.isHighlighted());1133 assertEquals('Control must have dispatched another HIGHLIGHT event', 2,1134 getEventCount(control, goog.ui.Component.EventType.HIGHLIGHT));1135}1136/**1137 * Tests {@link goog.ui.Control#isActive}.1138 */1139function testIsActive() {1140 assertFalse('Controls must not be active by default', control.isActive());1141}1142/**1143 * Tests {@link goog.ui.Control#setActive}.1144 */1145function testSetActive() {1146 control.setSupportedState(goog.ui.Component.State.ACTIVE, false);1147 control.setActive(true);1148 assertFalse('Control must not be active, because it isn\'t activateable',1149 control.isActive());1150 assertTrue('Control must not have dispatched any events',1151 noEventsDispatched());1152 control.setSupportedState(goog.ui.Component.State.ACTIVE, true);1153 control.setActive(true);1154 assertTrue('Control must be active', control.isActive());1155 assertEquals('Control must have dispatched an ACTIVATE event', 1,1156 getEventCount(control, goog.ui.Component.EventType.ACTIVATE));1157 control.setActive(true);1158 assertTrue('Control must still be active', control.isActive());1159 assertEquals('Control must not dispatch more ACTIVATE events', 1,1160 getEventCount(control, goog.ui.Component.EventType.ACTIVATE));1161 control.setEnabled(false);1162 assertFalse('Control must be disabled', control.isEnabled());1163 assertFalse('Control must not be active', control.isActive());1164 assertEquals('Control must have dispatched a DEACTIVATE event', 1,1165 getEventCount(control, goog.ui.Component.EventType.DEACTIVATE));1166}1167/**1168 * Tests disposing the control from an action event handler.1169 */1170function testDisposeOnAction() {1171 goog.events.listen(control, goog.ui.Component.EventType.ACTION,1172 function(e) {1173 control.dispose();1174 });1175 // Control must not throw an exception if disposed of in an ACTION event1176 // handler.1177 control.performActionInternal();1178 control.setActive(true);1179 assertTrue('Control should have been disposed of', control.isDisposed());1180}1181/**1182 * Tests {@link goog.ui.Control#isSelected}.1183 */1184function testIsSelected() {1185 assertFalse('Controls must not be selected by default',1186 control.isSelected());1187}1188/**1189 * Tests {@link goog.ui.Control#setSelected}.1190 */1191function testSetSelected() {1192 control.setSupportedState(goog.ui.Component.State.SELECTED, false);1193 control.setSelected(true);1194 assertFalse('Control must not be selected, because it isn\'t selectable',1195 control.isSelected());1196 assertTrue('Control must not have dispatched any events',1197 noEventsDispatched());1198 control.setSupportedState(goog.ui.Component.State.SELECTED, true);1199 control.setSelected(true);1200 assertTrue('Control must be selected', control.isSelected());1201 assertEquals('Control must have dispatched a SELECT event', 1,1202 getEventCount(control, goog.ui.Component.EventType.SELECT));1203 control.setSelected(true);1204 assertTrue('Control must still be selected', control.isSelected());1205 assertEquals('Control must not dispatch more SELECT events', 1,1206 getEventCount(control, goog.ui.Component.EventType.SELECT));1207 control.setSelected(false);1208 assertFalse('Control must not be selected', control.isSelected());1209 assertEquals('Control must have dispatched an UNSELECT event', 1,1210 getEventCount(control, goog.ui.Component.EventType.UNSELECT));1211 control.setEnabled(false);1212 assertFalse('Control must be disabled', control.isEnabled());1213 control.setSelected(true);1214 assertTrue('Control must be selected, even when disabled',1215 control.isSelected());1216 assertEquals('Control must have dispatched another SELECT event', 2,1217 getEventCount(control, goog.ui.Component.EventType.SELECT));1218}1219/**1220 * Tests {@link goog.ui.Control#isChecked}.1221 */1222function testIsChecked() {1223 assertFalse('Controls must not be checked by default',1224 control.isChecked());1225}1226/**1227 * Tests {@link goog.ui.Control#setChecked}.1228 */1229function testSetChecked() {1230 control.setSupportedState(goog.ui.Component.State.CHECKED, false);1231 control.setChecked(true);1232 assertFalse('Control must not be checked, because it isn\'t checkable',1233 control.isChecked());1234 assertTrue('Control must not have dispatched any events',1235 noEventsDispatched());1236 control.setSupportedState(goog.ui.Component.State.CHECKED, true);1237 control.setChecked(true);1238 assertTrue('Control must be checked', control.isChecked());1239 assertEquals('Control must have dispatched a CHECK event', 1,1240 getEventCount(control, goog.ui.Component.EventType.CHECK));1241 control.setChecked(true);1242 assertTrue('Control must still be checked', control.isChecked());1243 assertEquals('Control must not dispatch more CHECK events', 1,1244 getEventCount(control, goog.ui.Component.EventType.CHECK));1245 control.setChecked(false);1246 assertFalse('Control must not be checked', control.isChecked());1247 assertEquals('Control must have dispatched an UNCHECK event', 1,1248 getEventCount(control, goog.ui.Component.EventType.UNCHECK));1249 control.setEnabled(false);1250 assertFalse('Control must be disabled', control.isEnabled());1251 control.setChecked(true);1252 assertTrue('Control must be checked, even when disabled',1253 control.isChecked());1254 assertEquals('Control must have dispatched another CHECK event', 2,1255 getEventCount(control, goog.ui.Component.EventType.CHECK));1256}1257/**1258 * Tests {@link goog.ui.Control#isFocused}.1259 */1260function testIsFocused() {1261 assertFalse('Controls must not be focused by default',1262 control.isFocused());1263}1264/**1265 * Tests {@link goog.ui.Control#setFocused}.1266 */1267function testSetFocused() {1268 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);1269 control.setFocused(true);1270 assertFalse('Control must not be focused, because it isn\'t focusable',1271 control.isFocused());1272 assertTrue('Control must not have dispatched any events',1273 noEventsDispatched());1274 control.setSupportedState(goog.ui.Component.State.FOCUSED, true);1275 control.setFocused(true);1276 assertTrue('Control must be focused', control.isFocused());1277 assertEquals('Control must have dispatched a FOCUS event', 1,1278 getEventCount(control, goog.ui.Component.EventType.FOCUS));1279 control.setFocused(true);1280 assertTrue('Control must still be focused', control.isFocused());1281 assertEquals('Control must not dispatch more FOCUS events', 1,1282 getEventCount(control, goog.ui.Component.EventType.FOCUS));1283 control.setFocused(false);1284 assertFalse('Control must not be focused', control.isFocused());1285 assertEquals('Control must have dispatched an BLUR event', 1,1286 getEventCount(control, goog.ui.Component.EventType.BLUR));1287 control.setEnabled(false);1288 assertFalse('Control must be disabled', control.isEnabled());1289 control.setFocused(true);1290 assertTrue('Control must be focused, even when disabled',1291 control.isFocused());1292 assertEquals('Control must have dispatched another FOCUS event', 2,1293 getEventCount(control, goog.ui.Component.EventType.FOCUS));1294}1295/**1296 * Tests {@link goog.ui.Control#isOpen}.1297 */1298function testIsOpen() {1299 assertFalse('Controls must not be open by default', control.isOpen());1300}1301/**1302 * Tests {@link goog.ui.Control#setOpen}.1303 */1304function testSetOpen() {1305 control.setSupportedState(goog.ui.Component.State.OPENED, false);1306 control.setOpen(true);1307 assertFalse('Control must not be opened, because it isn\'t openable',1308 control.isOpen());1309 assertTrue('Control must not have dispatched any events',1310 noEventsDispatched());1311 control.setSupportedState(goog.ui.Component.State.OPENED, true);1312 control.setOpen(true);1313 assertTrue('Control must be opened', control.isOpen());1314 assertEquals('Control must have dispatched a OPEN event', 1,1315 getEventCount(control, goog.ui.Component.EventType.OPEN));1316 control.setOpen(true);1317 assertTrue('Control must still be opened', control.isOpen());1318 assertEquals('Control must not dispatch more OPEN events', 1,1319 getEventCount(control, goog.ui.Component.EventType.OPEN));1320 control.setOpen(false);1321 assertFalse('Control must not be opened', control.isOpen());1322 assertEquals('Control must have dispatched an CLOSE event', 1,1323 getEventCount(control, goog.ui.Component.EventType.CLOSE));1324 control.setEnabled(false);1325 assertFalse('Control must be disabled', control.isEnabled());1326 control.setOpen(true);1327 assertTrue('Control must be opened, even when disabled',1328 control.isOpen());1329 assertEquals('Control must have dispatched another OPEN event', 2,1330 getEventCount(control, goog.ui.Component.EventType.OPEN));1331}1332/**1333 * Tests {@link goog.ui.Control#getState}.1334 */1335function testGetState() {1336 assertEquals('Controls must be in the default state', 0x00,1337 control.getState());1338}1339/**1340 * Tests {@link goog.ui.Control#hasState}.1341 */1342function testHasState() {1343 assertFalse('Control must not be disabled',1344 control.hasState(goog.ui.Component.State.DISABLED));1345 assertFalse('Control must not be in the HOVER state',1346 control.hasState(goog.ui.Component.State.HOVER));1347 assertFalse('Control must not be active',1348 control.hasState(goog.ui.Component.State.ACTIVE));1349 assertFalse('Control must not be selected',1350 control.hasState(goog.ui.Component.State.SELECTED));1351 assertFalse('Control must not be checked',1352 control.hasState(goog.ui.Component.State.CHECKED));1353 assertFalse('Control must not be focused',1354 control.hasState(goog.ui.Component.State.FOCUSED));1355 assertFalse('Control must not be open',1356 control.hasState(goog.ui.Component.State.OPEN));1357}1358/**1359 * Tests {@link goog.ui.Control#setState}.1360 */1361function testSetState() {1362 control.createDom();1363 control.setSupportedState(goog.ui.Component.State.ACTIVE, false);1364 assertFalse('Control must not be active',1365 control.hasState(goog.ui.Component.State.ACTIVE));1366 control.setState(goog.ui.Component.State.ACTIVE, true);1367 assertFalse('Control must still be inactive (because it doesn\'t ' +1368 'support the ACTIVE state)',1369 control.hasState(goog.ui.Component.State.ACTIVE));1370 control.setSupportedState(goog.ui.Component.State.ACTIVE, true);1371 control.setState(goog.ui.Component.State.ACTIVE, true);1372 assertTrue('Control must be active',1373 control.hasState(goog.ui.Component.State.ACTIVE));1374 assertTrue('Control must have the active CSS style',1375 goog.dom.classlist.contains(control.getElement(),1376 'goog-control-active'));1377 control.setState(goog.ui.Component.State.ACTIVE, true);1378 assertTrue('Control must still be active',1379 control.hasState(goog.ui.Component.State.ACTIVE));1380 assertTrue('Control must still have the active CSS style',1381 goog.dom.classlist.contains(control.getElement(),1382 'goog-control-active'));1383 assertTrue('No events must have been dispatched', noEventsDispatched());1384}1385/**1386 * Tests {@link goog.ui.Control#setStateInternal}.1387 */1388function testSetStateInternal() {1389 control.setStateInternal(0x00);1390 assertEquals('State should be 0x00', 0x00, control.getState());1391 control.setStateInternal(0x17);1392 assertEquals('State should be 0x17', 0x17, control.getState());1393}1394/**1395 * Tests {@link goog.ui.Control#isSupportedState}.1396 */1397function testIsSupportedState() {1398 assertTrue('Control must support DISABLED',1399 control.isSupportedState(goog.ui.Component.State.DISABLED));1400 assertTrue('Control must support HOVER',1401 control.isSupportedState(goog.ui.Component.State.HOVER));1402 assertTrue('Control must support ACTIVE',1403 control.isSupportedState(goog.ui.Component.State.ACTIVE));1404 assertTrue('Control must support FOCUSED',1405 control.isSupportedState(goog.ui.Component.State.FOCUSED));1406 assertFalse('Control must no support SELECTED',1407 control.isSupportedState(goog.ui.Component.State.SELECTED));1408 assertFalse('Control must no support CHECKED',1409 control.isSupportedState(goog.ui.Component.State.CHECKED));1410 assertFalse('Control must no support OPENED',1411 control.isSupportedState(goog.ui.Component.State.OPENED));1412}1413/**1414 * Tests {@link goog.ui.Control#setSupportedState}.1415 */1416function testSetSupportedState() {1417 control.setSupportedState(goog.ui.Component.State.HOVER, true);1418 assertTrue('Control must still support HOVER',1419 control.isSupportedState(goog.ui.Component.State.HOVER));1420 control.setSupportedState(goog.ui.Component.State.HOVER, false);1421 assertFalse('Control must no longer support HOVER',1422 control.isSupportedState(goog.ui.Component.State.HOVER));1423 control.setState(goog.ui.Component.State.ACTIVE, true);1424 control.setSupportedState(goog.ui.Component.State.ACTIVE, false);1425 assertFalse('Control must no longer support ACTIVE',1426 control.isSupportedState(goog.ui.Component.State.ACTIVE));1427 assertFalse('Control must no longer be in the ACTIVE state',1428 control.hasState(goog.ui.Component.State.ACTIVE));1429 control.render(sandbox);1430 control.setSupportedState(goog.ui.Component.State.FOCUSED, true);1431 control.setState(goog.ui.Component.State.FOCUSED, true);1432 assertThrows('Must not be able to disable support for the FOCUSED ' +1433 "state for a control that's already in the document and focused",1434 function() {1435 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);1436 });1437 assertTrue('No events must have been dispatched', noEventsDispatched());1438}1439/**1440 * Tests {@link goog.ui.Control#isAutoState}.1441 */1442function testIsAutoState() {1443 assertTrue('Control must have DISABLED as an auto-state',1444 control.isAutoState(goog.ui.Component.State.DISABLED));1445 assertTrue('Control must have HOVER as an auto-state',1446 control.isAutoState(goog.ui.Component.State.HOVER));1447 assertTrue('Control must have ACTIVE as an auto-state',1448 control.isAutoState(goog.ui.Component.State.ACTIVE));1449 assertTrue('Control must have FOCUSED as an auto-state',1450 control.isAutoState(goog.ui.Component.State.FOCUSED));1451 assertFalse('Control must not have SELECTED as an auto-state',1452 control.isAutoState(goog.ui.Component.State.SELECTED));1453 assertFalse('Control must not have CHECKED as an auto-state',1454 control.isAutoState(goog.ui.Component.State.CHECKED));1455 assertFalse('Control must not have OPENED as an auto-state',1456 control.isAutoState(goog.ui.Component.State.OPENED));1457 assertTrue('No events must have been dispatched', noEventsDispatched());1458}1459/**1460 * Tests {@link goog.ui.Control#setAutoStates}.1461 */1462function testSetAutoStates() {1463 control.setAutoStates(goog.ui.Component.State.HOVER, false);1464 assertFalse('Control must not have HOVER as an auto-state',1465 control.isAutoState(goog.ui.Component.State.HOVER));1466 control.setAutoStates(goog.ui.Component.State.ACTIVE |1467 goog.ui.Component.State.FOCUSED, false);1468 assertFalse('Control must not have ACTIVE as an auto-state',1469 control.isAutoState(goog.ui.Component.State.ACTIVE));1470 assertFalse('Control must not have FOCUSED as an auto-state',1471 control.isAutoState(goog.ui.Component.State.FOCUSED));1472 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);1473 control.setAutoStates(goog.ui.Component.State.FOCUSED, true);1474 assertFalse('Control must not have FOCUSED as an auto-state if it no ' +1475 'longer supports FOCUSED',1476 control.isAutoState(goog.ui.Component.State.FOCUSED));1477 assertTrue('No events must have been dispatched', noEventsDispatched());1478}1479/**1480 * Tests {@link goog.ui.Control#isDispatchTransitionEvents}.1481 */1482function testIsDispatchTransitionEvents() {1483 assertTrue('Control must dispatch DISABLED transition events',1484 control.isDispatchTransitionEvents(goog.ui.Component.State.DISABLED));1485 assertTrue('Control must dispatch HOVER transition events',1486 control.isDispatchTransitionEvents(goog.ui.Component.State.HOVER));1487 assertTrue('Control must dispatch ACTIVE transition events',1488 control.isDispatchTransitionEvents(goog.ui.Component.State.ACTIVE));1489 assertTrue('Control must dispatch FOCUSED transition events',1490 control.isDispatchTransitionEvents(goog.ui.Component.State.FOCUSED));1491 assertFalse('Control must not dispatch SELECTED transition events',1492 control.isDispatchTransitionEvents(goog.ui.Component.State.SELECTED));1493 assertFalse('Control must not dispatch CHECKED transition events',1494 control.isDispatchTransitionEvents(goog.ui.Component.State.CHECKED));1495 assertFalse('Control must not dispatch OPENED transition events',1496 control.isDispatchTransitionEvents(goog.ui.Component.State.OPENED));1497 assertTrue('No events must have been dispatched', noEventsDispatched());1498}1499/**1500 * Tests {@link goog.ui.Control#setDispatchTransitionEvents}.1501 */1502function testSetDispatchTransitionEvents() {1503 control.setDispatchTransitionEvents(goog.ui.Component.State.HOVER, false);1504 assertFalse('Control must not dispatch HOVER transition events',1505 control.isDispatchTransitionEvents(goog.ui.Component.State.HOVER));1506 control.setSupportedState(goog.ui.Component.State.SELECTED, true);1507 control.setDispatchTransitionEvents(goog.ui.Component.State.SELECTED,1508 true);1509 assertTrue('Control must dispatch SELECTED transition events',1510 control.isDispatchTransitionEvents(goog.ui.Component.State.SELECTED));1511 assertTrue('No events must have been dispatched', noEventsDispatched());1512}1513/**1514 * Tests {@link goog.ui.Control#isTransitionAllowed}.1515 */1516function testIsTransitionAllowed() {1517 assertTrue('Control must support the HOVER state',1518 control.isSupportedState(goog.ui.Component.State.HOVER));1519 assertFalse('Control must not be in the HOVER state',1520 control.hasState(goog.ui.Component.State.HOVER));1521 assertTrue('Control must dispatch HOVER transition events',1522 control.isDispatchTransitionEvents(goog.ui.Component.State.HOVER));1523 assertTrue('Control must be allowed to transition to the HOVER state',1524 control.isTransitionAllowed(goog.ui.Component.State.HOVER, true));1525 assertEquals('Control must have dispatched one HIGHLIGHT event', 1,1526 getEventCount(control, goog.ui.Component.EventType.HIGHLIGHT));1527 assertFalse('Control must not be highlighted',1528 control.hasState(goog.ui.Component.State.HOVER));1529 control.setState(goog.ui.Component.State.HOVER, true);1530 control.setDispatchTransitionEvents(goog.ui.Component.State.HOVER, false);1531 assertTrue('Control must be allowed to transition from the HOVER state',1532 control.isTransitionAllowed(goog.ui.Component.State.HOVER, false));1533 assertEquals('Control must not have dispatched any UNHIGHLIGHT events', 0,1534 getEventCount(control, goog.ui.Component.EventType.UNHIGHLIGHT));1535 assertTrue('Control must still be highlighted',1536 control.hasState(goog.ui.Component.State.HOVER));1537 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);1538 resetEventCount();1539 assertFalse('Control doesn\'t support the FOCUSED state',1540 control.isSupportedState(goog.ui.Component.State.FOCUSED));1541 assertFalse('Control must not be FOCUSED',1542 control.hasState(goog.ui.Component.State.FOCUSED));1543 assertFalse('Control must not be allowed to transition to the FOCUSED ' +1544 'state',1545 control.isTransitionAllowed(goog.ui.Component.State.FOCUSED, true));1546 assertEquals('Control must not have dispatched any FOCUS events', 0,1547 getEventCount(control, goog.ui.Component.EventType.FOCUS));1548 control.setEnabled(false);1549 resetEventCount();1550 assertTrue('Control must support the DISABLED state',1551 control.isSupportedState(goog.ui.Component.State.DISABLED));1552 assertTrue('Control must be DISABLED',1553 control.hasState(goog.ui.Component.State.DISABLED));1554 assertFalse('Control must not be allowed to transition to the DISABLED ' +1555 'state, because it is already there',1556 control.isTransitionAllowed(goog.ui.Component.State.DISABLED, true));1557 assertEquals('Control must not have dispatched any ENABLE events', 0,1558 getEventCount(control, goog.ui.Component.EventType.ENABLE));1559}1560/**1561 * Tests {@link goog.ui.Control#handleKeyEvent}.1562 */1563function testHandleKeyEvent() {1564 control.render();1565 control.isVisible = control.isEnabled = function() {1566 return true;1567 };1568 goog.testing.events.fireKeySequence(1569 control.getKeyEventTarget(), goog.events.KeyCodes.A);1570 assertEquals('Control must not have dispatched an ACTION event', 0,1571 getEventCount(control, goog.ui.Component.EventType.ACTION));1572 goog.testing.events.fireKeySequence(1573 control.getKeyEventTarget(), goog.events.KeyCodes.ENTER);1574 assertEquals('Control must have dispatched an ACTION event', 1,1575 getEventCount(control, goog.ui.Component.EventType.ACTION));1576}1577/**1578 * Tests {@link goog.ui.Control#performActionInternal}.1579 */1580function testPerformActionInternal() {1581 assertFalse('Control must not be checked', control.isChecked());1582 assertFalse('Control must not be selected', control.isSelected());1583 assertFalse('Control must not be open', control.isOpen());1584 control.performActionInternal();1585 assertFalse('Control must not be checked', control.isChecked());1586 assertFalse('Control must not be selected', control.isSelected());1587 assertFalse('Control must not be open', control.isOpen());1588 assertEquals('Control must have dispatched an ACTION event', 1,1589 getEventCount(control, goog.ui.Component.EventType.ACTION));1590 control.setSupportedState(goog.ui.Component.State.CHECKED, true);1591 control.setSupportedState(goog.ui.Component.State.SELECTED, true);1592 control.setSupportedState(goog.ui.Component.State.OPENED, true);1593 control.performActionInternal();1594 assertTrue('Control must be checked', control.isChecked());1595 assertTrue('Control must be selected', control.isSelected());1596 assertTrue('Control must be open', control.isOpen());1597 assertEquals('Control must have dispatched a CHECK event', 1,1598 getEventCount(control, goog.ui.Component.EventType.CHECK));1599 assertEquals('Control must have dispatched a SELECT event', 1,1600 getEventCount(control, goog.ui.Component.EventType.SELECT));1601 assertEquals('Control must have dispatched a OPEN event', 1,1602 getEventCount(control, goog.ui.Component.EventType.OPEN));1603 assertEquals('Control must have dispatched another ACTION event', 2,1604 getEventCount(control, goog.ui.Component.EventType.ACTION));1605 control.performActionInternal();1606 assertFalse('Control must not be checked', control.isChecked());1607 assertTrue('Control must be selected', control.isSelected());1608 assertFalse('Control must not be open', control.isOpen());1609 assertEquals('Control must have dispatched an UNCHECK event', 1,1610 getEventCount(control, goog.ui.Component.EventType.UNCHECK));1611 assertEquals('Control must not have dispatched an UNSELECT event', 0,1612 getEventCount(control, goog.ui.Component.EventType.UNSELECT));1613 assertEquals('Control must have dispatched a CLOSE event', 1,1614 getEventCount(control, goog.ui.Component.EventType.CLOSE));1615 assertEquals('Control must have dispatched another ACTION event', 3,1616 getEventCount(control, goog.ui.Component.EventType.ACTION));1617}1618/**1619 * Tests {@link goog.ui.Control#handleMouseOver}.1620 */1621function testHandleMouseOver() {1622 control.setContent(goog.dom.createDom(goog.dom.TagName.SPAN, {id: 'caption'},1623 'Hello'));1624 control.render(sandbox);1625 var element = control.getElement();1626 var caption = goog.dom.getElement('caption');1627 // Verify baseline assumptions.1628 assertTrue('Caption must be contained within the control',1629 goog.dom.contains(element, caption));1630 assertTrue('Control must be enabled', control.isEnabled());1631 assertTrue('HOVER must be an auto-state',1632 control.isAutoState(goog.ui.Component.State.HOVER));1633 assertFalse('Control must not start out highlighted',1634 control.isHighlighted());1635 // Scenario 1: relatedTarget is contained within the control's DOM.1636 goog.testing.events.fireMouseOverEvent(element, caption);1637 assertTrue('No events must have been dispatched for internal mouse move',1638 noEventsDispatched());1639 assertFalse('Control must not be highlighted for internal mouse move',1640 control.isHighlighted());1641 resetEventCount();1642 // Scenario 2: preventDefault() is called on the ENTER event.1643 var key = goog.events.listen(control, goog.ui.Component.EventType.ENTER,1644 function(e) {1645 e.preventDefault();1646 });1647 goog.testing.events.fireMouseOverEvent(element, sandbox);1648 assertEquals('Control must have dispatched 1 ENTER event', 1,1649 getEventCount(control, goog.ui.Component.EventType.ENTER));1650 assertFalse('Control must not be highlighted if ENTER is canceled',1651 control.isHighlighted());1652 goog.events.unlistenByKey(key);1653 resetEventCount();1654 // Scenario 3: Control is disabled.1655 control.setEnabled(false);1656 goog.testing.events.fireMouseOverEvent(element, sandbox);1657 assertEquals('Control must dispatch ENTER event on mouseover even if ' +1658 'disabled', 1,1659 getEventCount(control, goog.ui.Component.EventType.ENTER));1660 assertFalse('Control must not be highlighted if it is disabled',1661 control.isHighlighted());1662 control.setEnabled(true);1663 resetEventCount();1664 // Scenario 4: HOVER is not an auto-state.1665 control.setAutoStates(goog.ui.Component.State.HOVER, false);1666 goog.testing.events.fireMouseOverEvent(element, sandbox);1667 assertEquals('Control must dispatch ENTER event on mouseover even if ' +1668 'HOVER is not an auto-state', 1,1669 getEventCount(control, goog.ui.Component.EventType.ENTER));1670 assertFalse('Control must not be highlighted if HOVER isn\'t an auto-' +1671 'state', control.isHighlighted());1672 control.setAutoStates(goog.ui.Component.State.HOVER, true);1673 resetEventCount();1674 // Scenario 5: All is well.1675 goog.testing.events.fireMouseOverEvent(element, sandbox);1676 assertEquals('Control must dispatch ENTER event on mouseover', 1,1677 getEventCount(control, goog.ui.Component.EventType.ENTER));1678 assertEquals('Control must dispatch HIGHLIGHT event on mouseover', 1,1679 getEventCount(control, goog.ui.Component.EventType.HIGHLIGHT));1680 assertTrue('Control must be highlighted', control.isHighlighted());1681 resetEventCount();1682 // Scenario 6: relatedTarget is null1683 control.setHighlighted(false);1684 goog.testing.events.fireMouseOverEvent(element, null);1685 assertEquals('Control must dispatch ENTER event on mouseover', 1,1686 getEventCount(control, goog.ui.Component.EventType.ENTER));1687 assertEquals('Control must dispatch HIGHLIGHT event on mouseover', 1,1688 getEventCount(control, goog.ui.Component.EventType.HIGHLIGHT));1689 assertTrue('Control must be highlighted', control.isHighlighted());1690 resetEventCount();1691}1692/**1693 * Tests {@link goog.ui.Control#handleMouseOut}.1694 */1695function testHandleMouseOut() {1696 control.setContent(goog.dom.createDom(goog.dom.TagName.SPAN, {id: 'caption'},1697 'Hello'));1698 control.setHighlighted(true);1699 control.setActive(true);1700 resetEventCount();1701 control.render(sandbox);1702 var element = control.getElement();1703 var caption = goog.dom.getElement('caption');1704 // Verify baseline assumptions.1705 assertTrue('Caption must be contained within the control',1706 goog.dom.contains(element, caption));1707 assertTrue('Control must be enabled', control.isEnabled());1708 assertTrue('HOVER must be an auto-state',1709 control.isAutoState(goog.ui.Component.State.HOVER));1710 assertTrue('ACTIVE must be an auto-state',1711 control.isAutoState(goog.ui.Component.State.ACTIVE));1712 assertTrue('Control must start out highlighted', control.isHighlighted());1713 assertTrue('Control must start out active', control.isActive());1714 // Scenario 1: relatedTarget is contained within the control's DOM.1715 goog.testing.events.fireMouseOutEvent(element, caption);1716 assertTrue('No events must have been dispatched for internal mouse move',1717 noEventsDispatched());1718 assertTrue('Control must not be un-highlighted for internal mouse move',1719 control.isHighlighted());1720 assertTrue('Control must not be deactivated for internal mouse move',1721 control.isActive());1722 resetEventCount();1723 // Scenario 2: preventDefault() is called on the LEAVE event.1724 var key = goog.events.listen(control, goog.ui.Component.EventType.LEAVE,1725 function(e) {1726 e.preventDefault();1727 });1728 goog.testing.events.fireMouseOutEvent(element, sandbox);1729 assertEquals('Control must have dispatched 1 LEAVE event', 1,1730 getEventCount(control, goog.ui.Component.EventType.LEAVE));1731 assertTrue('Control must not be un-highlighted if LEAVE is canceled',1732 control.isHighlighted());1733 assertTrue('Control must not be deactivated if LEAVE is canceled',1734 control.isActive());1735 goog.events.unlistenByKey(key);1736 resetEventCount();1737 // Scenario 3: ACTIVE is not an auto-state.1738 control.setAutoStates(goog.ui.Component.State.ACTIVE, false);1739 goog.testing.events.fireMouseOutEvent(element, sandbox);1740 assertEquals('Control must dispatch LEAVE event on mouseout even if ' +1741 'ACTIVE is not an auto-state', 1,1742 getEventCount(control, goog.ui.Component.EventType.LEAVE));1743 assertTrue('Control must not be deactivated if ACTIVE isn\'t an auto-' +1744 'state', control.isActive());1745 assertFalse('Control must be un-highlighted even if ACTIVE isn\'t an ' +1746 'auto-state', control.isHighlighted());1747 control.setAutoStates(goog.ui.Component.State.ACTIVE, true);1748 control.setHighlighted(true);1749 resetEventCount();1750 // Scenario 4: HOVER is not an auto-state.1751 control.setAutoStates(goog.ui.Component.State.HOVER, false);1752 goog.testing.events.fireMouseOutEvent(element, sandbox);1753 assertEquals('Control must dispatch LEAVE event on mouseout even if ' +1754 'HOVER is not an auto-state', 1,1755 getEventCount(control, goog.ui.Component.EventType.LEAVE));1756 assertFalse('Control must be deactivated even if HOVER isn\'t an auto-' +1757 'state', control.isActive());1758 assertTrue('Control must not be un-highlighted if HOVER isn\'t an auto-' +1759 'state', control.isHighlighted());1760 control.setAutoStates(goog.ui.Component.State.HOVER, true);1761 control.setActive(true);1762 resetEventCount();1763 // Scenario 5: All is well.1764 goog.testing.events.fireMouseOutEvent(element, sandbox);1765 assertEquals('Control must dispatch LEAVE event on mouseout', 1,1766 getEventCount(control, goog.ui.Component.EventType.LEAVE));1767 assertEquals('Control must dispatch DEACTIVATE event on mouseout', 1,1768 getEventCount(control, goog.ui.Component.EventType.DEACTIVATE));1769 assertEquals('Control must dispatch UNHIGHLIGHT event on mouseout', 1,1770 getEventCount(control, goog.ui.Component.EventType.UNHIGHLIGHT));1771 assertFalse('Control must be deactivated', control.isActive());1772 assertFalse('Control must be unhighlighted', control.isHighlighted());1773 resetEventCount();1774 // Scenario 6: relatedTarget is null1775 control.setActive(true);1776 control.setHighlighted(true);1777 goog.testing.events.fireMouseOutEvent(element, null);1778 assertEquals('Control must dispatch LEAVE event on mouseout', 1,1779 getEventCount(control, goog.ui.Component.EventType.LEAVE));1780 assertEquals('Control must dispatch DEACTIVATE event on mouseout', 1,1781 getEventCount(control, goog.ui.Component.EventType.DEACTIVATE));1782 assertEquals('Control must dispatch UNHIGHLIGHT event on mouseout', 1,1783 getEventCount(control, goog.ui.Component.EventType.UNHIGHLIGHT));1784 assertFalse('Control must be deactivated', control.isActive());1785 assertFalse('Control must be unhighlighted', control.isHighlighted());1786 resetEventCount();1787}1788function testIsMouseEventWithinElement() {1789 var child = goog.dom.createElement(goog.dom.TagName.DIV);1790 var parent = goog.dom.createDom(goog.dom.TagName.DIV, null, child);1791 var notChild = goog.dom.createElement(goog.dom.TagName.DIV);1792 var event = new goog.testing.events.Event('mouseout');1793 event.relatedTarget = child;1794 assertTrue('Event is within element',1795 goog.ui.Control.isMouseEventWithinElement_(event, parent));1796 var event = new goog.testing.events.Event('mouseout');1797 event.relatedTarget = notChild;1798 assertFalse('Event is not within element',1799 goog.ui.Control.isMouseEventWithinElement_(event, parent));1800}1801function testHandleMouseDown() {1802 control.render(sandbox);1803 assertFalse('preventDefault() must have been called for control that ' +1804 'doesn\'t support text selection',1805 fireMouseDownAndFocus(control.getElement()));1806 assertTrue('Control must be highlighted', control.isHighlighted());1807 assertTrue('Control must be active', control.isActive());1808 if (testFocus) {1809 // Expected to fail on IE and Mac Safari 3. IE calls focus handlers1810 // asynchronously, and Mac Safari 3 doesn't support keyboard focus.1811 expectedFailures.expectFailureFor(goog.userAgent.IE);1812 expectedFailures.expectFailureFor(isMacSafari3());1813 try {1814 assertTrue('Control must be focused', control.isFocused());1815 } catch (e) {1816 expectedFailures.handleException(e);1817 }1818 }1819}1820function testHandleMouseDownForDisabledControl() {1821 control.setEnabled(false);1822 control.render(sandbox);1823 assertFalse('preventDefault() must have been called for control that ' +1824 'doesn\'t support text selection',1825 fireMouseDownAndFocus(control.getElement()));1826 assertFalse('Control must not be highlighted', control.isHighlighted());1827 assertFalse('Control must not be active', control.isActive());1828 if (testFocus) {1829 assertFalse('Control must not be focused', control.isFocused());1830 }1831}1832function testHandleMouseDownForNoHoverAutoState() {1833 control.setAutoStates(goog.ui.Component.State.HOVER, false);1834 control.render(sandbox);1835 assertFalse('preventDefault() must have been called for control that ' +1836 'doesn\'t support text selection',1837 fireMouseDownAndFocus(control.getElement()));1838 assertFalse('Control must not be highlighted', control.isHighlighted());1839 assertTrue('Control must be active', control.isActive());1840 if (testFocus) {1841 // Expected to fail on IE and Mac Safari 3. IE calls focus handlers1842 // asynchronously, and Mac Safari 3 doesn't support keyboard focus.1843 expectedFailures.expectFailureFor(goog.userAgent.IE);1844 expectedFailures.expectFailureFor(isMacSafari3());1845 try {1846 assertTrue('Control must be focused', control.isFocused());1847 } catch (e) {1848 expectedFailures.handleException(e);1849 }1850 }1851}1852function testHandleMouseDownForRightMouseButton() {1853 control.render(sandbox);1854 assertTrue('preventDefault() must not have been called for right ' +1855 'mouse button', fireMouseDownAndFocus(control.getElement(),1856 goog.events.BrowserEvent.MouseButton.RIGHT));1857 assertTrue('Control must be highlighted', control.isHighlighted());1858 assertFalse('Control must not be active', control.isActive());1859 if (testFocus) {1860 // Expected to fail on IE and Mac Safari 3. IE calls focus handlers1861 // asynchronously, and Mac Safari 3 doesn't support keyboard focus.1862 expectedFailures.expectFailureFor(goog.userAgent.IE);1863 expectedFailures.expectFailureFor(isMacSafari3());1864 try {1865 assertTrue('Control must be focused', control.isFocused());1866 } catch (e) {1867 expectedFailures.handleException(e);1868 }1869 }1870}1871function testHandleMouseDownForNoActiveAutoState() {1872 control.setAutoStates(goog.ui.Component.State.ACTIVE, false);1873 control.render(sandbox);1874 assertFalse('preventDefault() must have been called for control that ' +1875 'doesn\'t support text selection',1876 fireMouseDownAndFocus(control.getElement()));1877 assertTrue('Control must be highlighted', control.isHighlighted());1878 assertFalse('Control must not be active', control.isActive());1879 if (testFocus) {1880 // Expected to fail on IE and Mac Safari 3. IE calls focus handlers1881 // asynchronously, and Mac Safari 3 doesn't support keyboard focus.1882 expectedFailures.expectFailureFor(goog.userAgent.IE);1883 expectedFailures.expectFailureFor(isMacSafari3());1884 try {1885 assertTrue('Control must be focused', control.isFocused());1886 } catch (e) {1887 expectedFailures.handleException(e);1888 }1889 }1890}1891function testHandleMouseDownForNonFocusableControl() {1892 control.setSupportedState(goog.ui.Component.State.FOCUSED, false);1893 control.render(sandbox);1894 assertFalse('preventDefault() must have been called for control that ' +1895 'doesn\'t support text selection',1896 fireMouseDownAndFocus(control.getElement()));1897 assertTrue('Control must be highlighted', control.isHighlighted());1898 assertTrue('Control must be active', control.isActive());1899 assertFalse('Control must not be focused', control.isFocused());1900}1901// TODO(attila): Find out why this is flaky on FF2/Linux and FF1.5/Win.1902//function testHandleMouseDownForSelectableControl() {1903// control.setAllowTextSelection(true);1904// control.render(sandbox);1905// assertTrue('preventDefault() must not have been called for control ' +1906// 'that supports text selection',1907// fireMouseDownAndFocus(control.getElement()));1908// assertTrue('Control must be highlighted', control.isHighlighted());1909// assertTrue('Control must be active', control.isActive());1910// // Expected to fail on IE and Mac Safari 3. IE calls focus handlers1911// // asynchronously, and Mac Safari 3 doesn't support keyboard focus.1912// expectedFailures.expectFailureFor(goog.userAgent.IE);1913// expectedFailures.expectFailureFor(isMacSafari3());1914// try {1915// assertTrue('Control must be focused', control.isFocused());1916// } catch (e) {1917// expectedFailures.handleException(e);1918// }1919//}1920/**1921 * Tests {@link goog.ui.Control#handleMouseUp}.1922 */1923function testHandleMouseUp() {1924 control.setActive(true);1925 // Override performActionInternal() for testing purposes.1926 var actionPerformed = false;1927 control.performActionInternal = function() {1928 actionPerformed = true;1929 return true;1930 };1931 resetEventCount();1932 control.render(sandbox);1933 var element = control.getElement();1934 // Verify baseline assumptions.1935 assertTrue('Control must be enabled', control.isEnabled());1936 assertTrue('HOVER must be an auto-state',1937 control.isAutoState(goog.ui.Component.State.HOVER));1938 assertTrue('ACTIVE must be an auto-state',1939 control.isAutoState(goog.ui.Component.State.ACTIVE));1940 assertFalse('Control must not start out highlighted',1941 control.isHighlighted());1942 assertTrue('Control must start out active', control.isActive());1943 // Scenario 1: Control is disabled.1944 control.setEnabled(false);1945 goog.testing.events.fireMouseUpEvent(element);1946 assertFalse('Disabled control must not highlight on mouseup',1947 control.isHighlighted());1948 assertFalse('No action must have been performed', actionPerformed);1949 control.setActive(true);1950 control.setEnabled(true);1951 // Scenario 2: HOVER is not an auto-state.1952 control.setAutoStates(goog.ui.Component.State.HOVER, false);1953 goog.testing.events.fireMouseUpEvent(element);1954 assertFalse('Control must not highlight on mouseup if HOVER isn\'t an ' +1955 'auto-state', control.isHighlighted());1956 assertTrue('Action must have been performed even if HOVER isn\'t an ' +1957 'auto-state', actionPerformed);1958 assertFalse('Control must have been deactivated on mouseup even if ' +1959 'HOVER isn\'t an auto-state', control.isActive());1960 actionPerformed = false;1961 control.setActive(true);1962 control.setAutoStates(goog.ui.Component.State.HOVER, true);1963 // Scenario 3: Control is not active.1964 control.setActive(false);1965 goog.testing.events.fireMouseUpEvent(element);1966 assertTrue('Control must highlight on mouseup, even if inactive',1967 control.isHighlighted());1968 assertFalse('No action must have been performed if control is inactive',1969 actionPerformed);1970 assertFalse('Inactive control must remain inactive after mouseup',1971 control.isActive());1972 control.setHighlighted(false);1973 control.setActive(true);1974 // Scenario 4: performActionInternal() returns false.1975 control.performActionInternal = function() {1976 actionPerformed = true;1977 return false;1978 };1979 goog.testing.events.fireMouseUpEvent(element);1980 assertTrue('Control must highlight on mouseup, even if no action is ' +1981 'performed', control.isHighlighted());1982 assertTrue('performActionInternal must have been called',1983 actionPerformed);1984 assertTrue('Control must not deactivate if performActionInternal ' +1985 'returns false', control.isActive());1986 control.setHighlighted(false);1987 actionPerformed = false;1988 control.performActionInternal = function() {1989 actionPerformed = true;1990 return true;1991 };1992 // Scenario 5: ACTIVE is not an auto-state.1993 control.setAutoStates(goog.ui.Component.State.ACTIVE, false);1994 goog.testing.events.fireMouseUpEvent(element);1995 assertTrue('Control must highlight on mouseup even if ACTIVE isn\'t an ' +1996 'auto-state', control.isHighlighted());1997 assertTrue('Action must have been performed even if ACTIVE isn\'t an ' +1998 'auto-state', actionPerformed);1999 assertTrue('Control must not have been deactivated on mouseup if ' +2000 'ACTIVE isn\'t an auto-state', control.isActive());2001 actionPerformed = false;2002 control.setHighlighted(false);2003 control.setAutoStates(goog.ui.Component.State.ACTIVE, true);2004 // Scenario 6: All is well.2005 goog.testing.events.fireMouseUpEvent(element);2006 assertTrue('Control must highlight on mouseup', control.isHighlighted());2007 assertTrue('Action must have been performed', actionPerformed);2008 assertFalse('Control must have been deactivated', control.isActive());2009}2010function testDefaultConstructor() {2011 var control = new goog.ui.Control();2012 assertNull(control.getContent());2013}2014function assertClickSequenceFires(msg) {2015 var actionCount = getEventCount(control, goog.ui.Component.EventType.ACTION);2016 goog.testing.events.fireClickSequence(control.getKeyEventTarget());2017 assertEquals(msg, actionCount + 1,2018 getEventCount(control, goog.ui.Component.EventType.ACTION));2019}2020function assertIsolatedClickFires(msg) {2021 var actionCount = getEventCount(control, goog.ui.Component.EventType.ACTION);2022 goog.testing.events.fireClickEvent(control.getKeyEventTarget());2023 assertEquals(msg, actionCount + 1,2024 getEventCount(control, goog.ui.Component.EventType.ACTION));2025}2026function assertIsolatedClickDoesNotFire(msg) {2027 var actionCount = getEventCount(control, goog.ui.Component.EventType.ACTION);2028 goog.testing.events.fireClickEvent(control.getKeyEventTarget());2029 assertEquals(msg, actionCount,2030 getEventCount(control, goog.ui.Component.EventType.ACTION));2031}2032function testIeMouseEventSequenceSimulator() {2033 control.render(sandbox);2034 // Click sequences and isolated clicks must be handled correctly in any order.2035 assertClickSequenceFires(2036 'ACTION event expected after a click sequence');2037 assertClickSequenceFires(2038 'ACTION event expected after a second consecutive click sequence');2039 if (goog.userAgent.IE) {2040 // For some reason in IE8 and perhaps earlier, isolated clicks do not result2041 // a detectable dispatch of an ACTION event, so we'll only assert the2042 // desired handling of isolated clicks in IE9 and higher.2043 if (goog.userAgent.isVersionOrHigher(9)) {2044 assertIsolatedClickFires(2045 'ACTION event expected after an isolated click immediately ' +2046 'following a click sequence');2047 assertIsolatedClickFires(2048 'ACTION event expected after second consecutive isolated click');2049 } else {2050 // For IE8-and-lower, fire an isolated click event in preparation for our2051 // final assertion.2052 goog.testing.events.fireClickEvent(control.getKeyEventTarget());2053 }2054 } else {2055 assertIsolatedClickDoesNotFire(2056 'No ACTION event expected after an isolated click immediately ' +2057 'following a click sequence');2058 assertIsolatedClickDoesNotFire(2059 'No ACTION event expected after second consecutive isolated click');2060 }2061 assertClickSequenceFires(2062 'ACTION event expected after click sequence immediately following ' +2063 'an isolated click ');...
themify.customize-control.js
Source:themify.customize-control.js
1/***************************************************************************2 *3 * ----------------------------------------------------------------------4 * DO NOT EDIT THIS FILE5 * ----------------------------------------------------------------------6 * Theme Customizer Scripts7 * Copyright (C) Themify8 *9 * ----------------------------------------------------------------------10 *11 ***************************************************************************/12(function (exports, $) {13 /**14 * Parse JSON string and returns object.15 *16 * Similar to $.parseJSON, however if parse fails returns an empty object instead of throwing errors.17 */18 function parseJSON( data ) {19 try {20 data = $.parseJSON( data );21 }22 catch( error ) {23 data = {};24 }25 return data;26 }27 'use strict';28 // Google Font Loader for fonts preview29 var wf = document.createElement('script'),30 s = document.getElementsByTagName('script')[0];31 wf.src = ('https:' == document.location.protocol ? 'https' : 'http') + '://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';32 wf.type = 'text/javascript';33 wf.async = 'true';34 s.parentNode.insertBefore(wf, s);35 var api = wp.customize,36 initialLoad = true;37 window.onbeforeunload = function () {38 if (!wp.customize.state('saved')()) {39 return themifyCustomizerControls.confirm_on_unload;40 }41 };42 function GetPrev( $this ) {43 var $prev = $this.prev( 'li' );44 return $prev.length > 0 && $prev.children( '.themify-control-title' ).length === 045 ? GetPrev($prev)46 : $prev.index();47 }48 api.bind( 'pane-contents-reflowed', function() {49 $( '.themify-subaccordion' ).each( function() {50 var $self = $( this ),51 thisGroup = $self.data( 'accordion' ),52 $li = $( '.' + thisGroup + '-group' );53 if( $li.is( '#customize-control-customcss_ctrl' ) ) {54 var scrollTop = $li.find( '.CodeMirror-scroll' ).scrollTop(),55 cm = $li.find( '.CodeMirror' ).get(0);56 $li.appendTo( $self );57 if( 'undefined' !== typeof cm && 'CodeMirror' in cm ) {58 cm.CodeMirror.focus();59 cm.CodeMirror.scrollTo( 0, scrollTop );60 }61 } else {62 $li.appendTo( $self );63 }64 65 var reverse = $( $li.get().reverse() );66 reverse.each( function() {67 if( $(this).children( '.themify-control-title' ).length === 0 ) {68 var $start_index = GetPrev( $( this ) );69 $( this ).appendTo( $li.eq( $start_index )70 .children( '.themify-control-sub-accordeon' ).first() );71 }72 });73 });74 $( 'li[id*="nav_menu_locations"]' ).each( function() {75 $( this ).appendTo( $( this ).prev().find( '.themify-subaccordion' ) );76 });77 if( initialLoad ) {78 $( '#accordion-section-themify_options:visible' ).find( '.accordion-section-title' ).trigger( 'click' );79 $( '.themify-suba-toggle.themify-control-title' ).unbind( 'click' ).click( function( e ) {80 e.preventDefault();81 var $sub_accordeon = $( this ).closest( 'li' ).find( '.themify-control-sub-accordeon' );82 if( $( this ).hasClass( 'topen' ) ) {83 $( this ).removeClass( 'topen' );84 $sub_accordeon.slideUp();85 } else {86 $( this ).addClass( 'topen' );87 $sub_accordeon.slideDown();88 }89 } );90 $('.themify-control-sub-accordeon').hide();91 $( 'body' ).on( 'mouseover', '.devices [data-device]', function( e ) {92 var $title = 'Styling: ' + $( this ).data( 'device' ).replace( '_', ' ' );93 $( this ).append( '<span class="themify_customize_tooltip">' + $title + '</span>' );94 } ).on( 'mouseout', '.devices [data-device]', function( e ) {95 $(this).children('.themify_customize_tooltip').remove();96 });97 $.event.trigger( "themify_customizer_ready" );98 initialLoad = false;99 }100 } );101 ////////////////////////////////////////////////////////////////////////////102 // Accordion Start103 ////////////////////////////////////////////////////////////////////////////104 api.ThemifySubAccordion = api.Control.extend({105 ready: function () {106 var control = this,107 $a = $('.themify-suba-toggle', control.container),108 $ul = $a.next();109 $('.customize-control.customize-control-themify_subaccordion_end').remove();110 $a.on('click', function (e) {111 e.preventDefault();112 $(this).parent().toggleClass('topen');113 $ul.toggleClass('tpanelopen');114 115 if($ul.hasClass('tpanelopen')){ 116 $ul.slideDown();117 }118 else{ 119 $ul.slideUp();120 }121 });122 var $navMenu = $('select[data-customize-setting-link^="nav_menu_locations"]', control.container);123 $navMenu.closest('label').map(function () {124 $(this).replaceWith($(this).contents());125 });126 $navMenu.wrap('<div class="themify-customizer-brick" />').wrap('<div class="custom-select nav-menu-select" />');127 }128 });129 api.controlConstructor.themify_subaccordion_start = api.ThemifySubAccordion;130 ////////////////////////////////////////////////////////////////////////////131 // Accordion End132 ////////////////////////////////////////////////////////////////////////////133 /***************************************************************************134 * ThemifyControl Start135 *136 * This Model serves as a foundation to derive the other controls.137 * When initializing an inherited Model, the ready() method must be defined.138 ***************************************************************************/139 api.ThemifyControl = api.Control.extend({140 value: {},141 /**142 * This property must be defined in inherited models.143 * Must be set to the class of the hidden text field that stores the settings.144 * Example: .themify_background_control145 */146 field: '',147 openMedia: function () {148 var control = this, $field = $(control.field, control.container),149 file_frame = '';150 $('.open-media', control.container).on('click', function (e) {151 e.preventDefault();152 file_frame = wp.media.frames.file_frame = wp.media({153 title: $(this).data('uploader-title'),154 library: {155 type: ['image']156 },157 button: {158 text: $(this).data('uploader-button-text')159 },160 multiple: false161 });162 file_frame.on('select', function () {163 var attachment = file_frame.state().get('selection').first().toJSON();164 var $imgPreview = $('<a href="#" class="remove-image ti-close"></a><img src="' + attachment.url + '" />').css('display', 'inline-block');165 var $preview = $('.themify_control_preview', control.container),166 $close = $('a', $preview),167 $imgPre = $('img', $preview);168 if ( control.isResponsiveStyling() ) {169 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 170 control.value[control.id][control.getCurrentDevice()] = {};171 172 control.value[control.id][control.getCurrentDevice()].id = attachment.id;173 control.value[control.id][control.getCurrentDevice()].src = attachment.url;174 } else {175 control.value[control.id].id = attachment.id;176 control.value[control.id].src = attachment.url;177 }178 $field.val(JSON.stringify(control.value[control.id])).trigger('change');179 if ($close.length > 0) {180 $close.remove();181 }182 if ($imgPre.length > 0) {183 $imgPre.remove();184 }185 $preview.append($imgPreview).fadeIn();186 });187 file_frame.open();188 });189 // Remove image190 $('.open-media-wrap', control.container).on('click', '.remove-image', function (e) {191 e.preventDefault();192 if ( control.isResponsiveStyling() ) {193 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 194 control.value[control.id][control.getCurrentDevice()] = {};195 196 //control.value[control.id][control.getCurrentDevice()] = _.omit( control.value[control.id][control.getCurrentDevice()], ['id', 'src'] );197 control.value[control.id][control.getCurrentDevice()].id = '';198 control.value[control.id][control.getCurrentDevice()].src = '';199 } else {200 control.value[control.id].id = '';201 control.value[control.id].src = '';202 }203 $field.val(JSON.stringify(control.value[control.id])).trigger('change');204 $(this).next().remove();205 $(this).remove();206 });207 },208 pickColor: function () {209 var control = this, $field = $(control.field, control.container),210 index = 0,211 $color = $('.color-select', control.container),212 $removeColor = $('.remove-color', control.container);213 214 // Color Picker215 $color.minicolors({216 defaultValue: '',217 letterCase: 'lowercase',218 opacity: true,219 swatches: themifyColorManager.toColorsArray(),220 show: function () {221 themifyColorManager.initColorPicker();222 var $self = $(this);223 if ($self.closest('li').is(':last-child')) {224 $self.closest('.color-picker').addClass('color-picker-visible');225 var $wpFullOverLaySidebar = $('.wp-full-overlay-sidebar-content');226 $wpFullOverLaySidebar.scrollTop($wpFullOverLaySidebar.scrollTop() + 140);227 }228 },229 change: function (hex, opacity) {230 if(control.id==='headerwrap_background_ctrl' && themifyCustomizerControls.header_transparnet && index<1){231 alert(themifyCustomizerControls.header_transparnet);232 index++;233 }234 if ( control.isResponsiveStyling() ) {235 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 236 control.value[control.id][control.getCurrentDevice()] = {};237 238 control.value[control.id][control.getCurrentDevice()].color = hex.replace('#', '');239 control.value[control.id][control.getCurrentDevice()].opacity = opacity;240 } else {241 control.value[control.id].color = hex.replace('#', '');242 control.value[control.id].opacity = opacity;243 }244 $field.val(JSON.stringify(control.value[control.id])).trigger('change');245 $removeColor.show();246 247 },248 hide: function () {249 if ('' != $(this).val()) {250 if ( control.isResponsiveStyling() ) {251 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 252 control.value[control.id][control.getCurrentDevice()] = {};253 control.value[control.id][control.getCurrentDevice()].color = $(this).val().replace('#', '');254 } else {255 control.value[control.id].color = $(this).val().replace('#', '');256 }257 $field.val(JSON.stringify(control.value[control.id])).trigger('change');258 $removeColor.show();259 }260 var $self = $(this);261 if ($self.closest('li').is(':last-child')) {262 $self.closest('.color-picker').removeClass('color-picker-visible');263 }264 }265 });266 // Clear color field267 $removeColor.on('click', function (e) {268 e.preventDefault();269 if ( control.isResponsiveStyling() ) {270 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 271 control.value[control.id][control.getCurrentDevice()] = {};272 control.value[control.id][control.getCurrentDevice()] = _.omit( control.value[control.id][control.getCurrentDevice()], 'color' );273 control.value[control.id][control.getCurrentDevice()] = _.omit( control.value[control.id][control.getCurrentDevice()], 'opacity' );274 } else {275 control.value[control.id] = _.omit( control.value[control.id], 'color' );276 control.value[control.id] = _.omit( control.value[control.id], 'opacity' ); 277 }278 279 $field.val(JSON.stringify(control.value[control.id])).trigger('change');280 $color.minicolors('value', '');281 $color.minicolors('opacity', '');282 $removeColor.hide();283 });284 },285 pickBorderColor: function () {286 var control = this, $field = $(control.field, control.container),287 $color = $('.color-select', control.container),288 $removeColor = $('.remove-color', control.container),289 $same = $('.same', control.container);290 // Color Picker291 $color.minicolors({292 defaultValue: '',293 letterCase: 'lowercase',294 opacity: true,295 swatches: themifyColorManager.toColorsArray(),296 change: function (hex, opacity) {297 var side = $(this).data('side'),298 color = hex.replace('#', '');299 if ($same.prop('checked')) {300 if ( control.isResponsiveStyling() ) {301 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 302 control.value[control.id][control.getCurrentDevice()] = {};303 control.value[control.id][control.getCurrentDevice()].color = color;304 control.value[control.id][control.getCurrentDevice()].opacity = opacity;305 control.value[control.id][control.getCurrentDevice()].same = 'same';306 } else {307 control.value[control.id].color = color;308 control.value[control.id].opacity = opacity;309 control.value[control.id].same = 'same';310 }311 } else {312 if ( control.isResponsiveStyling() ) {313 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 314 control.value[control.id][control.getCurrentDevice()] = {};315 control.value[control.id][control.getCurrentDevice()][side] = _.extend({}, control.value[control.id][control.getCurrentDevice()][side], {316 'color': color,317 'opacity': opacity318 });319 if ('top' === side) {320 control.value[control.id][control.getCurrentDevice()].color = color;321 control.value[control.id][control.getCurrentDevice()].opacity = opacity;322 }323 control.value[control.id][control.getCurrentDevice()].same = '';324 } else {325 control.value[control.id][side] = _.extend({}, control.value[control.id][side], {326 'color': color,327 'opacity': opacity328 });329 if ('top' === side) {330 control.value[control.id].color = color;331 control.value[control.id].opacity = opacity;332 }333 control.value[control.id].same = '';334 }335 }336 control.setting.set('{}', {silent: true});337 $field.val(JSON.stringify(control.value[control.id])).trigger('change');338 $(this).parent().next().show();339 },340 hide: function () {341 if ($(this).val()) {342 var hex = $(this).val(),343 side = $(this).data('side'),344 color = hex.replace('#', '');345 if ($same.prop('checked')) {346 if ( control.isResponsiveStyling() ) {347 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 348 control.value[control.id][control.getCurrentDevice()] = {};349 control.value[control.id][control.getCurrentDevice()].color = color;350 control.value[control.id][control.getCurrentDevice()].same = 'same';351 } else {352 control.value[control.id].color = color;353 control.value[control.id].same = 'same';354 }355 } else {356 if ( control.isResponsiveStyling() ) {357 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 358 control.value[control.id][control.getCurrentDevice()] = {};359 control.value[control.id][control.getCurrentDevice()][side] = _.extend({}, control.value[control.id][control.getCurrentDevice()][side], {360 'color': color361 });362 if ('top' === side) {363 control.value[control.id][control.getCurrentDevice()].color = color;364 }365 control.value[control.id][control.getCurrentDevice()].same = '';366 } else {367 control.value[control.id][side] = _.extend({}, control.value[control.id][side], {368 'color': color369 });370 if ('top' === side) {371 control.value[control.id].color = color;372 }373 control.value[control.id].same = '';374 }375 }376 $field.val(JSON.stringify(control.value[control.id])).trigger('change');377 $(this).parent().next().show();378 }379 },380 show:function(){381 themifyColorManager.initColorPicker();382 }383 });384 // Clear color field385 $removeColor.on('click', function (e) {386 e.preventDefault();387 var side = $(this).data('side');388 if ($same.prop('checked')) {389 if ( control.isResponsiveStyling() ) {390 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 391 control.value[control.id][control.getCurrentDevice()] = {};392 control.value[control.id][control.getCurrentDevice()] = _.omit( control.value[control.id][control.getCurrentDevice()], ['color', 'opacity'] ); 393 control.value[control.id][control.getCurrentDevice()].same = 'same';394 } else {395 control.value[control.id].color = '';396 control.value[control.id].opacity = '';397 control.value[control.id].same = 'same';398 }399 } else {400 if ( control.isResponsiveStyling() ) {401 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 402 control.value[control.id][control.getCurrentDevice()] = {};403 control.value[control.id][control.getCurrentDevice()][side] = _.extend({}, control.value[control.id][control.getCurrentDevice()][side], {404 'color': '',405 'opacity': ''406 });407 if ('top' === side) {408 control.value[control.id][control.getCurrentDevice()] = _.omit( control.value[control.id][control.getCurrentDevice()], ['color', 'opacity']);409 }410 control.value[control.id][control.getCurrentDevice()].same = '';411 } else {412 control.value[control.id][side] = _.extend({}, control.value[control.id][side], {413 'color': '',414 'opacity': ''415 });416 if ('top' === side) {417 control.value[control.id].color = '';418 control.value[control.id].opacity = '';419 }420 control.value[control.id].same = '';421 }422 }423 $field.val(JSON.stringify(control.value[control.id])).trigger('change');424 var $color = $(this).siblings('.minicolors').children('.color-select');425 $color.minicolors('value', '');426 $color.minicolors('opacity', '');427 $(this).hide();428 });429 },430 transparent: function ($obj) {431 var control = this, $field = $(control.field, control.container);432 $obj.on('click', function () {433 var $self = $(this);434 if ($self.prop('checked')) {435 if ( control.isResponsiveStyling() ) {436 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 437 control.value[control.id][control.getCurrentDevice()] = {};438 439 control.value[control.id][control.getCurrentDevice()].transparent = 'transparent';440 } else {441 control.value[control.id].transparent = 'transparent';442 }443 $self.parent().prev().addClass('transparent');444 } else {445 if ( control.isResponsiveStyling() ) {446 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 447 control.value[control.id][control.getCurrentDevice()] = {};448 449 control.value[control.id][control.getCurrentDevice()].transparent = '';450 } else {451 control.value[control.id].transparent = '';452 }453 $self.parent().prev().removeClass('transparent');454 }455 $field.val(JSON.stringify(control.value[control.id])).trigger('change');456 });457 if ($obj.prop('checked')) {458 $obj.parent().prev().addClass('transparent');459 }460 },461 dropdown: function ($obj, key) {462 var control = this, $field = $(control.field, control.container);463 $obj.on('change', function () {464 var value = control.value[control.id],465 device = control.getCurrentDevice(),466 currentVal = $( 'option:selected', $(this) ).val();467 if ( control.isResponsiveStyling() ) {468 _.isUndefined( value[device] ) && ( value[device] = {} );469 value[device][key] = currentVal;470 } else {471 value[key] = currentVal;472 }473 $field.val( JSON.stringify( value ) ).trigger( 'change' );474 });475 },476 collapse: function ($obj) {477 var control = this, $field = $(control.field, control.container);478 $obj.on('click', function () {479 var $self = $(this);480 if ($self.prop('checked')) {481 control.value[control.id].disabled = 'disabled';482 $self.parent().siblings('.themify-customizer-brick').stop().slideUp();483 } else {484 control.value[control.id].disabled = '';485 var $same = $self.parent().parent().find('input[type="checkbox"].same');486 if ($same.length > 0 && $same.prop('checked')) {487 $self.parent().siblings('.useforall, .collapse-same').stop().slideDown();488 } else {489 $self.parent().siblings('.themify-customizer-brick').stop().slideDown();490 }491 }492 $field.val(JSON.stringify(control.value[control.id])).trigger('change');493 });494 if ($obj.prop('checked')) {495 $obj.parent().siblings('.themify-customizer-brick').hide();496 }497 },498 input: function ($obj, key) {499 var control = this, $field = $(control.field, control.container);500 $obj.on('keyup', function () {501 if ( control.isResponsiveStyling() ) {502 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 503 control.value[control.id][control.getCurrentDevice()] = {};504 505 control.value[control.id][control.getCurrentDevice()][key] = $(this).val();506 } else {507 control.value[control.id][key] = $(this).val();508 }509 $field.val(JSON.stringify(control.value[control.id])).trigger('change');510 });511 },512 dimension: function ($obj) {513 var control = this, $field = $(control.field, control.container);514 $obj.on('keyup', function () {515 var value = control.value[control.id],516 device = control.getCurrentDevice(),517 width = $(this).val();518 if( control.isResponsiveStyling() ) {519 _.isUndefined( value[device] ) && ( value[device] = {} );520 value[device].width = width;521 } else {522 value.width = width;523 }524 $field.val( JSON.stringify( value ) ).trigger( 'change' );525 });526 },527 dimensionSame: function ($obj) {528 var control = this, $field = $(control.field, control.container),529 $same = $('.same', control.container);530 $obj.on('keyup', function () {531 var side = $(this).data('side'),532 width = $(this).val();533 if ($same.prop('checked')) {534 if ( control.isResponsiveStyling() ) {535 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 536 control.value[control.id][control.getCurrentDevice()] = {};537 538 control.value[control.id][control.getCurrentDevice()].width = width;539 control.value[control.id][control.getCurrentDevice()].same = 'same';540 } else {541 control.value[control.id].width = width;542 control.value[control.id].same = 'same';543 }544 } else {545 if ( control.isResponsiveStyling() ) {546 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 547 control.value[control.id][control.getCurrentDevice()] = {};548 549 control.value[control.id][control.getCurrentDevice()][side] = _.extend({}, control.value[control.id][control.getCurrentDevice()][side], {550 'width': width551 });552 if ('top' === side) {553 control.value[control.id][control.getCurrentDevice()].width = width;554 }555 control.value[control.id][control.getCurrentDevice()].same = '';556 } else {557 control.value[control.id][side] = _.extend({}, control.value[control.id][side], {558 'width': width559 });560 if ('top' === side) {561 control.value[control.id].width = width;562 }563 control.value[control.id].same = '';564 }565 }566 $field.val(JSON.stringify(control.value[control.id])).trigger('change');567 });568 },569 auto: function ( $obj ) {570 var control = this, $field = $( control.field, control.container ),571 hide = $obj.data( 'hide' ),572 hideEl = $( control.container ).find( '.' + hide );573 $obj.on('click', function () {574 var $self = $(this),575 value = control.value[control.id],576 device = control.getCurrentDevice(),577 currentVal = $self.prop( 'checked' ) ? 'auto' : '';578 if( control.isResponsiveStyling() ) {579 _.isUndefined( value[device] ) && ( value[device] = {} );580 value[device].auto = currentVal;581 } else {582 value.auto = currentVal;583 }584 hideEl.stop().toggleClass( 'hide-horizontally', currentVal );585 $field.val( JSON.stringify( value ) ).trigger( 'change' );586 });587 $obj.prop( 'checked' ) && hideEl.addClass( 'hide-horizontally' );588 },589 autoSame: function ($obj) {590 var control = this, $field = $(control.field, control.container),591 $same = $('.same', control.container);592 $obj.on('click', function () {593 var $self = $(this),594 hide = $self.data('hide'),595 side = $(this).data('side'),596 obj = {};597 if ($same.prop('checked')) {598 if ($self.prop('checked')) {599 obj.auto = 'auto';600 if ( control.isResponsiveStyling() ) {601 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 602 control.value[control.id][control.getCurrentDevice()] = {};603 604 control.value[control.id][control.getCurrentDevice()].auto = 'auto';605 control.value[control.id][control.getCurrentDevice()].top = _.extend({}, control.value[control.id][control.getCurrentDevice()].top, obj);606 } else {607 control.value[control.id].auto = 'auto';608 control.value[control.id].top = _.extend({}, control.value[control.id].top, obj);609 }610 $(control.container).find('.' + hide).stop().addClass('hide-horizontally');611 } else {612 obj.auto = '';613 if ( control.isResponsiveStyling() ) {614 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 615 control.value[control.id][control.getCurrentDevice()] = {};616 617 control.value[control.id][control.getCurrentDevice()].auto = '';618 control.value[control.id][control.getCurrentDevice()].top = _.extend({}, control.value[control.id][control.getCurrentDevice()].top, obj);619 } else {620 control.value[control.id].auto = '';621 control.value[control.id].top = _.extend({}, control.value[control.id].top, obj);622 }623 $(control.container).find('.' + hide).stop().removeClass('hide-horizontally');624 }625 if ( control.isResponsiveStyling() ) {626 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 627 control.value[control.id][control.getCurrentDevice()] = {};628 629 control.value[control.id][control.getCurrentDevice()].same = 'same';630 } else {631 control.value[control.id].same = 'same';632 }633 } else {634 if ($self.prop('checked')) {635 obj.auto = 'auto';636 637 if ( control.isResponsiveStyling() ) {638 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 639 control.value[control.id][control.getCurrentDevice()] = {};640 641 control.value[control.id][control.getCurrentDevice()][side] = _.extend({}, control.value[control.id][control.getCurrentDevice()][side], obj);642 if ('top' === side) {643 control.value[control.id][control.getCurrentDevice()].auto = 'auto';644 }645 } else {646 control.value[control.id][side] = _.extend({}, control.value[control.id][side], obj);647 if ('top' === side) {648 control.value[control.id].auto = 'auto';649 }650 }651 $(control.container).find('.' + hide).stop().addClass('hide-horizontally');652 } else {653 obj.auto = '';654 if ( control.isResponsiveStyling() ) {655 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 656 control.value[control.id][control.getCurrentDevice()] = {};657 658 control.value[control.id][control.getCurrentDevice()][side] = _.extend({}, control.value[control.id][control.getCurrentDevice()][side], obj);659 if ('top' === side) {660 control.value[control.id][control.getCurrentDevice()].auto = '';661 }662 } else {663 control.value[control.id][side] = _.extend({}, control.value[control.id][side], obj);664 if ('top' === side) {665 control.value[control.id].auto = '';666 }667 }668 $(control.container).find('.' + hide).stop().removeClass('hide-horizontally');669 }670 if ( control.isResponsiveStyling() ) {671 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 672 control.value[control.id][control.getCurrentDevice()] = {};673 674 control.value[control.id][control.getCurrentDevice()].same = '';675 } else {676 control.value[control.id].same = '';677 }678 }679 $field.val(JSON.stringify(control.value[control.id])).trigger('change');680 });681 $obj.each(function () {682 var $self = $(this),683 hide = $self.data('hide');684 if ($self.prop('checked')) {685 $(control.container).find('.' + hide).addClass('hide-horizontally');686 }687 });688 },689 dropdownSame: function ($obj, key) {690 var control = this, $field = $(control.field, control.container),691 $same = $('.same', control.container);692 $obj.on('change', function () {693 var side = $(this).data('side'),694 val = $('option:selected', $(this)).val();695 if ($same.prop('checked')) {696 if ( control.isResponsiveStyling() ) {697 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 698 control.value[control.id][control.getCurrentDevice()] = {};699 700 control.value[control.id][control.getCurrentDevice()][key] = val;701 control.value[control.id][control.getCurrentDevice()].same = 'same';702 } else {703 control.value[control.id][key] = val;704 control.value[control.id].same = 'same';705 }706 } else {707 var obj = {};708 obj[key] = val;709 if ( control.isResponsiveStyling() ) {710 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 711 control.value[control.id][control.getCurrentDevice()] = {};712 713 control.value[control.id][control.getCurrentDevice()][side] = _.extend({}, control.value[control.id][control.getCurrentDevice()][side], obj);714 if ('top' === side) {715 control.value[control.id][control.getCurrentDevice()][key] = val;716 }717 control.value[control.id][control.getCurrentDevice()].same = '';718 } else {719 control.value[control.id][side] = _.extend({}, control.value[control.id][side], obj);720 if ('top' === side) {721 control.value[control.id][key] = val;722 }723 control.value[control.id].same = '';724 }725 }726 $field.val(JSON.stringify(control.value[control.id])).trigger('change');727 });728 },729 dropdownBorderSame: function ($obj) {730 var control = this, $field = $(control.field, control.container),731 $same = $('.same', control.container);732 $obj.on('change', function () {733 var $self = $(this),734 side = $self.data('side'),735 style = $('option:selected', $self).val();736 if ($same.prop('checked')) {737 if ( control.isResponsiveStyling() ) {738 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 739 control.value[control.id][control.getCurrentDevice()] = {};740 741 control.value[control.id][control.getCurrentDevice()].style = style;742 control.value[control.id][control.getCurrentDevice()].same = 'same';743 } else {744 control.value[control.id].style = style;745 control.value[control.id].same = 'same';746 }747 } else {748 if ( control.isResponsiveStyling() ) {749 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 750 control.value[control.id][control.getCurrentDevice()] = {};751 752 control.value[control.id][control.getCurrentDevice()][side] = _.extend({}, control.value[control.id][control.getCurrentDevice()][side], {753 'style': style754 });755 if ('top' === side) {756 control.value[control.id][control.getCurrentDevice()].style = style;757 }758 control.value[control.id][control.getCurrentDevice()].same = '';759 } else {760 control.value[control.id][side] = _.extend({}, control.value[control.id][side], {761 'style': style762 });763 if ('top' === side) {764 control.value[control.id].style = style;765 }766 control.value[control.id].same = '';767 }768 }769 $field.val(JSON.stringify(control.value[control.id])).trigger('change');770 if ('none' === style) {771 $self.parent().siblings('.color-picker, .border-width, .dimension-unit-label').hide();772 } else {773 $self.parent().siblings('.color-picker, .border-width, .dimension-unit-label').show();774 }775 });776 $obj.each(function () {777 var $self = $(this),778 style = $('option:selected', $self).val();779 if ('none' === style) {780 $self.parent().siblings('.color-picker, .border-width, .dimension-unit-label').hide();781 } else {782 $self.parent().siblings('.color-picker, .border-width, .dimension-unit-label').show();783 }784 });785 },786 hideComponentsSame: function ($obj) {787 var control = this, $field = $(control.field, control.container),788 $components = $('.component', control.container),789 $rowLabel = $('.dimension-row-label:not(.same-label)', control.container),790 $sameLabel = $obj.parent().parent().find('.same-label');791 $obj.on('click', function () {792 var $self = $(this);793 if ($self.prop('checked')) {794 if ( control.isResponsiveStyling() ) {795 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 796 control.value[control.id][control.getCurrentDevice()] = {};797 798 control.value[control.id][control.getCurrentDevice()].same = 'same';799 } else {800 control.value[control.id].same = 'same';801 }802 $components.stop().slideUp();803 $rowLabel.hide();804 $sameLabel.text($sameLabel.data('same'));805 } else {806 if ( control.isResponsiveStyling() ) {807 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 808 control.value[control.id][control.getCurrentDevice()] = {};809 810 control.value[control.id][control.getCurrentDevice()].same = '';811 } else {812 control.value[control.id].same = '';813 }814 $components.stop().slideDown();815 $rowLabel.show();816 $sameLabel.text($sameLabel.data('notsame'));817 }818 $field.val(JSON.stringify(control.value[control.id])).trigger('change');819 });820 if ($obj.prop('checked')) {821 $components.hide();822 $rowLabel.hide();823 $sameLabel.text($sameLabel.data('same'));824 }825 },826 getSelectedData: function ($obj, data, std) {827 var $op = $('.selected', $obj),828 dataget = $op.data(data);829 return dataget ? dataget : std;830 },831 fontStyle: function ($style) {832 var control = this, $field = $(control.field, control.container);833 // Font style834 $('.button', $style).on('click', function () {835 var clickedStyle = $(this).data('style');836 if ('underline' === clickedStyle) {837 $('.button.selected[data-style="linethrough"]', $style).removeClass('selected');838 }839 if ('linethrough' === clickedStyle) {840 $('.button.selected[data-style="underline"]', $style).removeClass('selected');841 }842 if ('italic' === clickedStyle) {843 $('.button.selected[data-style="normal"]', $style).removeClass('selected');844 }845 if ('normal' === clickedStyle) {846 $('.button.selected[data-style="italic"]', $style).removeClass('selected');847 }848 if ('nostyle' === clickedStyle) {849 $('.button:not([data-style="nostyle"])', $style).removeClass('selected');850 }851 if ('nostyle' !== clickedStyle) {852 $('.button[data-style="nostyle"]', $style).removeClass('selected');853 }854 // Mark this as selected855 $(this).toggleClass('selected');856 // Check which buttons are set857 if ( control.isResponsiveStyling() ) {858 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 859 control.value[control.id][control.getCurrentDevice()] = {};860 861 $('.button', $style).each(function () {862 control.value[control.id][control.getCurrentDevice()][$(this).data('style')] = $(this).hasClass('selected') ? $(this).data('style') : '';863 });864 } else {865 $('.button', $style).each(function () {866 control.value[control.id][$(this).data('style')] = $(this).hasClass('selected') ? $(this).data('style') : '';867 });868 }869 $field.val(JSON.stringify(control.value[control.id])).trigger('change');870 });871 },872 textTransform: function ($texttransform) {873 var control = this, $field = $(control.field, control.container);874 $('.button', $texttransform).on('click', function () {875 var clickedTextTrans = $(this).data('texttransform');876 // Mark this as selected877 $('.button', $texttransform).not(this).removeClass('selected');878 $(this).toggleClass('selected');879 if ('notexttransform' === clickedTextTrans) {880 $('.button:not([data-texttransform="notexttransform"])', $texttransform).removeClass('selected');881 }882 else {883 $('.button[data-texttransform="notexttransform"]', $texttransform).removeClass('selected');884 }885 if ( control.isResponsiveStyling() ) {886 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 887 control.value[control.id][control.getCurrentDevice()] = {};888 control.value[control.id][control.getCurrentDevice()].texttransform = control.getSelectedData($texttransform, 'texttransform');889 } else {890 control.value[control.id].texttransform = control.getSelectedData($texttransform, 'texttransform');891 }892 $field.val(JSON.stringify(control.value[control.id])).trigger('change');893 });894 },895 textAlign: function ($align) {896 var control = this, $field = $(control.field, control.container);897 $('.button', $align).on('click', function () {898 var clickedAlign = $(this).data('align');899 // Mark this as selected900 $('.button', $align).not(this).removeClass('selected');901 $(this).toggleClass('selected');902 if ('noalign' === clickedAlign) {903 $('.button:not([data-align="noalign"])', $align).removeClass('selected');904 }905 if ('noalign' !== clickedAlign) {906 $('.button[data-align="noalign"]', $align).removeClass('selected');907 }908 if ( control.isResponsiveStyling() ) {909 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 910 control.value[control.id][control.getCurrentDevice()] = {};911 control.value[control.id][control.getCurrentDevice()].align = control.getSelectedData($align, 'align');912 } else {913 control.value[control.id].align = control.getSelectedData($align, 'align');914 }915 $field.val(JSON.stringify(control.value[control.id])).trigger('change');916 });917 },918 fontFamily: function ($obj) {919 var control = this, $field = $(control.field, control.container);920 $obj.on({921 change: function () {922 var $font_weight = $(this).closest('li').find('.font_weight_select'),923 $variants = $font_weight.length>0?$(this).find('option:selected').data('variants'):false;924 if ( control.isResponsiveStyling() ) {925 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 926 control.value[control.id][control.getCurrentDevice()] = {};927 control.value[control.id][control.getCurrentDevice()].family = parseJSON($('option:selected', $(this)).val());928 929 } else {930 control.value[control.id].family = parseJSON($('option:selected', $(this)).val());931 }932 if($variants){933 $variants = $.trim($variants).split(',');934 $font_weight.find('option').each(function(){935 if($.inArray($(this).val(),$variants)===-1){936 $(this).hide();937 }938 else{939 $(this).show();940 }941 });942 var $selected = $font_weight.find('option:selected');943 if(!$selected.is(':visible')){944 $selected.prop('selected',false);945 $font_weight.find('option').each(function(){946 if ($(this).css('display') != 'none') {947 $(this).prop("selected", true).trigger('change');948 return false;949 }950 });951 }952 }953 else{954 $font_weight.find('option').show();955 }956 $field.val(JSON.stringify(control.value[control.id])).trigger('change');957 $('#themify_font_preview').hide();958 },959 focusin: function () {960 var $selected = $(this).data('selected');961 if ($('.themify_add_fonts').length > 0) {962 var $html = $('.themify_add_fonts').html(),963 $options = $($html);964 $options.find('option').removeAttr('selected');965 if ($selected) {966 $options.find('option[data-value="' + $selected + '"]').attr('selected', 'selected');967 }968 $(this).html($options);969 }970 else {971 $('body').append('<span id="themify_font_preview"><span class="themify_font_wait"></span>Font Preview</span>');972 var $themify_fonts = parseJSON(decodeURI($('#themify_fonts_hidden').val())),973 $cf_fonts = $themify_fonts.cf,974 $google = $themify_fonts.google,975 $fonts = $themify_fonts.fonts,976 $html = '';977 $themify_fonts = null;978 if($cf_fonts.length>0){979 for (var $i in $cf_fonts) {980 var $name = $cf_fonts[$i].name,981 $value = $cf_fonts[$i].value;982 $s = $selected && $selected == $value ? 'selected="selected"' : '';983 $val = '{"fonttype":"cf"';984 if ($cf_fonts[$i].subsets) {985 $val += ',"subsets":"' + control.escapeHtml($cf_fonts[$i].subsets) + "'";986 }987 $name = control.escapeHtml($name);988 $val += ',"name":"' + $value + '"}';989 $html += "<option data-variants='"+$cf_fonts[$i].variant+"' data-value='" + $value + "' class='cf_font' " + $s + " value='" + $val + "'>" + $name + "</option>";990 }991 $cf_fonts = null;992 $(this).children('optgroup').first().html($html);993 $html = '';994 }995 for (var $i in $fonts) {996 var $name = $fonts[$i].value,997 $s = $selected && $selected == $name ? 'selected="selected"' : '';998 $name = control.escapeHtml($name);999 var $val = '{"fonttype":"websafe","name":"' + $name + '"}';1000 $html += "<option " + $s + " data-value='" + $name + "' value='" + $val + "'>" + $fonts[$i].name + "</option>";1001 }1002 $fonts = null;1003 $(this).children('optgroup.themify_wsf_optgroup').html($html);1004 $html = '';1005 for (var $i in $google) {1006 var $name = $google[$i].name,1007 $s = $selected && $selected == $name ? 'selected="selected"' : '';1008 $val = '{"fonttype":"google"';1009 if ($google[$i].subsets) {1010 $val += ',"subsets":"' + control.escapeHtml($google[$i].subsets) + "'";1011 }1012 $name = control.escapeHtml($name);1013 $val += ',"name":"' + $name + '"}';1014 $html += "<option data-variants='"+$google[$i].variant+"' data-value='" + $name + "' class='google_font' " + $s + " value='" + $val + "'>" + $google[$i].name + "</option>";1015 }1016 $google = null;1017 $(this).children('optgroup').last().html($html);1018 $(this).addClass('themify_add_fonts');1019 $('#themify_fonts_hidden').remove();1020 control.fontHover();1021 }1022 var $this = $(this);1023 $this.off('focusin').scombobox({1024 wrap: true,1025 reassignId: false,1026 empty: $selected ? false : true,1027 showDropDown: true,1028 beforeClose: function () {1029 $('#themify_font_preview').hide();1030 },1031 afterClose: function () {1032 var $input = $this.closest('.scombobox').find('.scombobox-display');1033 if (!$.trim($input.val())) {1034 $this.data('selected', '')1035 .find('option:selected')1036 .prop('selected', false)1037 .trigger('change');1038 }1039 if($('#themify_font_preview').is(':visible') && !$this.find('.scombobox-list').is(':visible')){1040 $('#themify_font_preview').hide();1041 }1042 },callback:{1043 func: function(){1044 this.scombobox('open');1045 }1046 }1047 });1048 }1049 });1050 },1051 escapeHtml: function ($string) {1052 var map = {1053 '&': '&',1054 '<': '<',1055 '>': '>',1056 '"': '"',1057 "'": '''1058 };1059 return $string.replace(/[&<>"']/g, function (m) {1060 return map[m];1061 });1062 },1063 fontHover: function () {1064 $('.themify_combobox').delegate('.scombobox-list p', 'hover', function (e) {1065 e.stopImmediatePropagation();1066 var $preview = $('#themify_font_preview');1067 if ($(this).data('value') && $(this).is(':visible')) {1068 var $font = parseJSON($(this).data('value')),1069 $pos = $(this).offset();1070 $preview.css({'top': $pos.top - 7, 'left': $pos.left + 260});1071 1072 if ( ( 'google' === $font.fonttype || 'cf' === $font.fonttype ) && !$(this).hasClass('themify_font_loaded')) {1073 $('.themify_combobox .scombobox-list p').removeClass('current');1074 $(this).addClass('current');1075 $preview.addClass('themify_show_wait');1076 setTimeout(function () {1077 var $this = $('.themify_combobox p.current');1078 if($this.closest('.scombobox-list').is(':visible')){1079 var $font = parseJSON($this.data('value')),1080 $pos = $this.offset(),1081 webFontConfig = {1082 fontloading: function (familyName, fvd) {1083 $preview.css('font-family', familyName).removeClass('themify_show_wait');1084 $this.addClass('themify_font_loaded');1085 }1086 };1087 $preview.css({'top': $pos.top - 7, 'left': $pos.left + 260}).show();1088 if('google' === $font.fonttype){1089 webFontConfig['google'] = {families: [$font.name]};1090 }else{1091 webFontConfig['custom'] = {families: [$font.name],urls:[themifyCustomizerControls.cf_api_url+$font.name]};1092 }1093 WebFont.load(webFontConfig);1094 }1095 else{1096 $preview.hide();1097 }1098 }, 800);1099 }1100 else {1101 $preview.css('font-family', $font.name).removeClass('themify_show_wait').show();1102 }1103 }1104 else {1105 $preview.hide();1106 }1107 });1108 },1109 inputOption: function ($obj, key) {1110 var control = this, $field = $(control.field, control.container),1111 timer;1112 $obj.on('keyup', function () {1113 var value = $(this).val();1114 if ('blogname' === key) {1115 $('.customize-control-themify_logo').find('.site-name').each(function () {1116 $(this).val(value);1117 });1118 }1119 clearTimeout(timer);1120 timer = setTimeout(function () {1121 $.post(1122 ajaxurl,1123 {1124 'action': 'themify_customizer_save_option',1125 'option': key,1126 'value': value,1127 'nonce': themifyCustomizerControls.nonce1128 },1129 function (data) {1130 if ('saved' === data) {1131 // Set timestamp to force live preview reload1132 control.value[control.id].stamp = new Date().getTime();1133 $field.val(JSON.stringify(control.value[control.id])).trigger('change');1134 }1135 }1136 );1137 }, 750);1138 });1139 },1140 saveOption: function (key, value) {1141 var control = this;1142 $.post(1143 ajaxurl,1144 {1145 'action': 'themify_customizer_save_option',1146 'option': key,1147 'value': value,1148 'nonce': themifyCustomizerControls.nonce1149 },1150 function (data) {1151 if ('saved' === data) {1152 control.saveOptionCallback();1153 }1154 }1155 );1156 },1157 saveOptionCallback: function () {1158 // if you use saveOption, redefine this callback in the extended object1159 },1160 changeMode: function (key) {1161 var control = this, $field = $(control.field, control.container);1162 $(key + '-mode', control.container).each(function () {1163 $(this).on('click', function () {1164 var $self = $(this);1165 $(key + '-mode-wrap', control.container).hide();1166 $(key + '-' + $self.val() + '-mode', control.container).show();1167 1168 control.value[control.id].mode = $self.val();1169 $field.val(JSON.stringify(control.value[control.id])).trigger('change');1170 });1171 });1172 $(key + '-mode-wrap', control.container).hide();1173 $(key + '-' + $('input[type="radio"]' + key + '-mode:checked').val() + '-mode', control.container).show();1174 },1175 addQueryArg: function (e, n, l) {1176 l = l || window.location.href;1177 var r, f = new RegExp("([?&])" + e + "=.*?(&|#|$)(.*)", "gi");1178 if (f.test(l))1179 return"undefined" !== typeof n && null !== n ? l.replace(f, "$1" + e + "=" + n + "$2$3") : (r = l.split("#"), l = r[0].replace(f, "$1$3").replace(/(&|\?)$/, ""), "undefined" !== typeof r[1] && null !== r[1] && (l += "#" + r[1]), l);1180 if ("undefined" !== typeof n && null !== n) {1181 var i = -1 !== l.indexOf("?") ? "&" : "?";1182 return r = l.split("#"), l = r[0] + i + e + "=" + n, "undefined" !== typeof r[1] && null !== r[1] && (l += "#" + r[1]), l1183 }1184 return l1185 },1186 getParameterByName: function(name, url) {1187 if (!url) {1188 url = window.location.href;1189 }1190 name = name.replace(/[\[\]]/g, "\\$&");1191 var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),1192 results = regex.exec(url);1193 if (!results) return null;1194 if (!results[2]) return '';1195 return decodeURIComponent(results[2].replace(/\+/g, " "));1196 },1197 isResponsiveStyling: function() {1198 return 'desktop' !== api.previewedDevice.get();1199 },1200 getCurrentDevice: function() {1201 return api.previewedDevice.get();1202 },1203 radioChange: function( $obj, key ) {1204 var control = this,1205 $field = $(control.field, control.container),1206 initVal = $obj.find( 'input[type="radio"]:checked' ).val();1207 $obj.find( 'input[type="radio"]' ).on('click', function () {1208 var val = $(this).val();1209 if ( control.isResponsiveStyling() ) {1210 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 1211 control.value[control.id][control.getCurrentDevice()] = {};1212 control.value[control.id][control.getCurrentDevice()][key] = val;1213 } else {1214 control.value[control.id][key] = val;1215 $obj.closest( '.customize-control' ).data( 'deskValue', val );1216 }1217 $obj.nextAll( '[class*="-mode-wrap"]' ).hide();1218 $obj.nextAll( '[class*="-' + val + '-mode"]' ).show();1219 $field.val(JSON.stringify(control.value[control.id])).trigger('change');1220 });1221 $obj.nextAll( '[class*="-mode-wrap"]' ).hide();1222 $obj.nextAll( '[class*="-' + initVal + '-mode"]' ).show();1223 }1224 });1225 /***************************************************************************1226 * ThemifyControl End1227 ***************************************************************************/1228 ////////////////////////////////////////////////////////////////////////////1229 // Font Control Start1230 ////////////////////////////////////////////////////////////////////////////1231 api.ThemifyFont = api.ThemifyControl.extend({1232 field: '.themify_font_control',1233 ready: function () {1234 var control = this,1235 $field = $(control.field, control.container);1236 control.value[control.id] = $field.val() ? parseJSON($field.val()) : {};1237 // Checkbox to hide controls1238 control.collapse($('.disable-control', control.container));1239 // Font family1240 control.fontFamily($('.themify_font_family', control.container));1241 // Font size numeric1242 control.input($('.font_size_num', control.container), 'sizenum');1243 // Font size unit1244 control.dropdown($('.font_size_unit', control.container), 'sizeunit');1245 // Letter spacing numeric1246 control.input($('.letter_spacing', control.container), 'letterspacing');1247 // Letter spacing unit1248 control.dropdown($('.letter_spacing_unit', control.container), 'letterspacingunit');1249 // Line height numeric1250 control.input($('.font_line_num', control.container), 'linenum');1251 // Line height unit1252 control.dropdown($('.font_line_unit', control.container), 'lineunit');1253 1254 // Font Weight1255 control.dropdown($('.font_weight_select', control.container), 'weight');1256 // Font style1257 control.fontStyle($('.themify_font_style', control.container));1258 // Text transform1259 control.textTransform($('.themify_text_transform', control.container));1260 // Text align1261 control.textAlign($('.themify_font_align', control.container));1262 }1263 });1264 api.controlConstructor.themify_font = api.ThemifyFont;1265 api.controlConstructor.themify_text_decoration = api.ThemifyFont;1266 ////////////////////////////////////////////////////////////////////////////1267 // Font Control End1268 ////////////////////////////////////////////////////////////////////////////1269 ////////////////////////////////////////////////////////////////////////////1270 // Logo Control Start1271 ////////////////////////////////////////////////////////////////////////////1272 api.ThemifyLogo = api.ThemifyControl.extend({1273 field: '.themify_logo_control',1274 ready: function () {1275 var control = this,1276 $field = $(control.field, control.container);1277 control.value[control.id] = $field.val() ? parseJSON($field.val()) : {};1278 // Site title1279 control.inputOption($('.site-name', control.container), 'blogname');1280 // Site title link1281 control.input($('.site-link', control.container), 'link');1282 // Open Media Library1283 control.openMedia();1284 // Image width and height1285 control.input($('.img-width', control.container), 'imgwidth');1286 control.input($('.img-height', control.container), 'imgheight');1287 // Checkbox to hide controls1288 control.collapse($('.disable-control', control.container));1289 // Font family1290 control.fontFamily($('.themify_font_family', control.container));1291 // Font size numeric1292 control.input($('.font_size_num', control.container), 'sizenum');1293 // Font size unit1294 control.dropdown($('.font_size_unit', control.container), 'sizeunit');1295 // Line height numeric1296 control.input($('.font_line_num', control.container), 'linenum');1297 // Line height unit1298 control.dropdown($('.font_line_unit', control.container), 'lineunit');1299 1300 // Letter spacing numeric1301 control.input($('.letter_spacing', control.container), 'letterspacing');1302 // Letter spacing unit1303 control.dropdown($('.letter_spacing_unit', control.container), 'letterspacingunit');1304 1305 // Font Weight1306 control.dropdown($('.font_weight_select', control.container), 'weight');1307 // Font style1308 control.fontStyle($('.themify_font_style', control.container));1309 // Text transform1310 control.textTransform($('.themify_text_transform', control.container));1311 // Text align1312 control.textAlign($('.themify_font_align', control.container));1313 // Color Picker1314 control.pickColor();1315 // Logo Mode Changer1316 control.radioChange( $( '.logo-modes', control.container ), 'mode' )1317 }1318 });1319 api.controlConstructor.themify_logo = api.ThemifyLogo;1320 ////////////////////////////////////////////////////////////////////////////1321 // Logo Control End1322 ////////////////////////////////////////////////////////////////////////////1323 ////////////////////////////////////////////////////////////////////////////1324 // Tagline Control Start1325 ////////////////////////////////////////////////////////////////////////////1326 api.ThemifyTagline = api.ThemifyControl.extend({1327 field: '.themify_tagline_control',1328 ready: function () {1329 var control = this,1330 $field = $(control.field, control.container);1331 control.value[control.id] = $field.val() ? parseJSON($field.val()) : {};1332 // Logo Mode Changer1333 control.changeMode('.tagline');1334 // Site title1335 control.inputOption($('.site-description', control.container), 'blogdescription');1336 // Open Media Library1337 control.openMedia();1338 // Image width and height1339 control.input($('.img-width', control.container), 'imgwidth');1340 control.input($('.img-height', control.container), 'imgheight');1341 // Checkbox to hide controls1342 control.collapse($('.disable-control', control.container));1343 // Font family1344 control.fontFamily($('.themify_font_family', control.container));1345 // Font size numeric1346 control.input($('.font_size_num', control.container), 'sizenum');1347 // Font size unit1348 control.dropdown($('.font_size_unit', control.container), 'sizeunit');1349 // Letter spacing numeric1350 control.input($('.letter_spacing', control.container), 'letterspacing');1351 // Letter spacing unit1352 control.dropdown($('.letter_spacing_unit', control.container), 'letterspacingunit');1353 // Line height numeric1354 control.input($('.font_line_num', control.container), 'linenum');1355 // Line height unit1356 control.dropdown($('.font_line_unit', control.container), 'lineunit');1357 1358 // Font Weight1359 control.dropdown($('.font_weight_select', control.container), 'weight');1360 // Font style1361 control.fontStyle($('.themify_font_style', control.container));1362 // Text transform1363 control.textTransform($('.themify_text_transform', control.container));1364 // Text align1365 control.textAlign($('.themify_font_align', control.container));1366 // Color Picker1367 control.pickColor();1368 // Site title link1369 control.input($('.site-description-link', control.container), 'link');1370 }1371 });1372 api.controlConstructor.themify_tagline = api.ThemifyTagline;1373 ////////////////////////////////////////////////////////////////////////////1374 // Logo Control End1375 ////////////////////////////////////////////////////////////////////////////1376 ////////////////////////////////////////////////////////////////////////////1377 // Background Control Start1378 ////////////////////////////////////////////////////////////////////////////1379 api.ThemifyBackground = api.ThemifyControl.extend({1380 field: '.themify_background_control',1381 noImage: function ($obj) {1382 var control = this, $field = $(control.field, control.container),1383 $hideElements = $('.open-media-wrap, .image-label, .background-style, .background-position', control.container);1384 $obj.on('click', function () {1385 var $self = $(this);1386 if ($self.prop('checked')) {1387 if ( control.isResponsiveStyling() ) {1388 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 1389 control.value[control.id][control.getCurrentDevice()] = {};1390 1391 control.value[control.id][control.getCurrentDevice()].noimage = 'noimage';1392 } else {1393 control.value[control.id].noimage = 'noimage';1394 }1395 $hideElements.stop().slideUp();1396 } else {1397 if ( control.isResponsiveStyling() ) {1398 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 1399 control.value[control.id][control.getCurrentDevice()] = {};1400 1401 control.value[control.id][control.getCurrentDevice()].noimage = '';1402 } else {1403 control.value[control.id].noimage = '';1404 }1405 $hideElements.stop().slideDown();1406 }1407 $field.val(JSON.stringify(control.value[control.id])).trigger('change');1408 });1409 if ($obj.prop('checked')) {1410 $hideElements.hide();1411 }1412 },1413 fixedBg: function( $obj ) {1414 var control = this, $field = $(control.field, control.container);1415 $obj.on('click', function () {1416 var $self = $(this);1417 if ($self.prop('checked')) {1418 if ( control.isResponsiveStyling() ) {1419 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 1420 control.value[control.id][control.getCurrentDevice()] = {};1421 1422 control.value[control.id][control.getCurrentDevice()].fixedbg = 'fixed';1423 } else {1424 control.value[control.id].fixedbg = 'fixed';1425 }1426 } else {1427 if ( control.isResponsiveStyling() ) {1428 if ( _.isUndefined( control.value[control.id][control.getCurrentDevice()] ) ) 1429 control.value[control.id][control.getCurrentDevice()] = {};1430 1431 control.value[control.id][control.getCurrentDevice()].fixedbg = '';1432 } else {1433 control.value[control.id].fixedbg = '';1434 }1435 }1436 $field.val(JSON.stringify(control.value[control.id])).trigger('change');1437 });1438 },1439 ready: function () {1440 var control = this,1441 $field = $(control.field, control.container);1442 control.value[control.id] = $field.val() ? parseJSON($field.val()) : {};1443 // Checkbox to hide controls1444 control.noImage($('.disable-control', control.container));1445 // Fixed Background1446 control.fixedBg( $( '.fixed-bg input[type="checkbox"]', control.container ) );1447 // Open Media Library1448 control.openMedia();1449 // Image style1450 control.dropdown($('.image-style', control.container), 'style');1451 // Image position1452 control.dropdown($('.position-style', control.container), 'position');1453 // Color Picker1454 control.pickColor();1455 // Color Transparent1456 control.transparent($('.color-transparent', control.container));1457 }1458 });1459 api.controlConstructor.themify_background = api.ThemifyBackground;1460 ////////////////////////////////////////////////////////////////////////////1461 // Background Control End1462 ////////////////////////////////////////////////////////////////////////////1463 ////////////////////////////////////////////////////////////////////////////1464 // Color Control Start1465 ////////////////////////////////////////////////////////////////////////////1466 api.ThemifyColor = api.ThemifyControl.extend({1467 field: '.themify_color_control',1468 ready: function () {1469 var control = this,1470 $field = $(control.field, control.container);1471 control.value[control.id] = $field.val() ? parseJSON($field.val()) : {};1472 // Color Picker1473 control.pickColor();1474 // Color Transparent1475 control.transparent($('.color-transparent', control.container));1476 }1477 });1478 api.controlConstructor.themify_color = api.ThemifyColor;1479 ////////////////////////////////////////////////////////////////////////////1480 // Color Control End1481 ////////////////////////////////////////////////////////////////////////////1482 ////////////////////////////////////////////////////////////////////////////1483 // Image Control Start1484 ////////////////////////////////////////////////////////////////////////////1485 api.ThemifyImage = api.ThemifyBackground.extend({1486 field: '.themify_image_control',1487 ready: function () {1488 var control = this,1489 $field = $(control.field, control.container);1490 control.value[control.id] = $field.val() ? parseJSON($field.val()) : {};1491 // Image width and height1492 control.input($('.img-width', control.container), 'imgwidth');1493 control.input($('.img-height', control.container), 'imgheight');1494 // Open Media Library1495 control.openMedia();1496 }1497 });1498 api.controlConstructor.themify_image = api.ThemifyImage;1499 ////////////////////////////////////////////////////////////////////////////1500 // Image Control End1501 ////////////////////////////////////////////////////////////////////////////1502 ////////////////////////////////////////////////////////////////////////////1503 // Border Control Start1504 ////////////////////////////////////////////////////////////////////////////1505 api.ThemifyBorder = api.ThemifyControl.extend({1506 field: '.themify_border_control',1507 ready: function () {1508 var control = this,1509 $field = $(control.field, control.container);1510 if ($field.val()) {1511 control.value[control.id] = parseJSON($field.val());1512 } else {1513 var initObj = {1514 'color': '',1515 'opacity': '',1516 'style': '',1517 'width': ''1518 };1519 control.value[control.id] = {};1520 control.value[control.id].top = initObj;1521 control.value[control.id].left = initObj;1522 control.value[control.id].bottom = initObj;1523 control.value[control.id].right = initObj;1524 }1525 // Checkbox to hide controls1526 control.collapse($('.disable-control', control.container));1527 // Border color1528 control.pickBorderColor();1529 // Border style1530 control.dropdownBorderSame($('.border-style', control.container));1531 // Border width1532 control.dimensionSame($('.dimension-width', control.container));1533 // Hide components leaving only one1534 control.hideComponentsSame($('.same', control.container));1535 }1536 });1537 api.controlConstructor.themify_border = api.ThemifyBorder;1538 ////////////////////////////////////////////////////////////////////////////1539 // Border Control End1540 ////////////////////////////////////////////////////////////////////////////1541 ////////////////////////////////////////////////////////////////////////////1542 // Margin Control Start1543 ////////////////////////////////////////////////////////////////////////////1544 api.ThemifyMargin = api.ThemifyControl.extend({1545 field: '.themify_margin_control',1546 ready: function () {1547 var control = this,1548 $field = $(control.field, control.container);1549 if ($field.val()) {1550 control.value[control.id] = parseJSON($field.val());1551 } else {1552 var initObj = {1553 'width': '',1554 'unit': 'px'1555 };1556 control.value[control.id] = {};1557 control.value[control.id].top = initObj;1558 control.value[control.id].left = initObj;1559 control.value[control.id].bottom = initObj;1560 control.value[control.id].right = initObj;1561 }1562 // Checkbox to hide controls1563 control.collapse($('.disable-control', control.container));1564 // Margin width1565 control.dimensionSame($('.dimension-width', control.container));1566 // Margin unit1567 control.dropdownSame($('.dimension-unit', control.container), 'unit');1568 // Auto1569 control.autoSame($('.auto-prop', control.container));1570 // Hide components leaving only one1571 control.hideComponentsSame($('.same', control.container));1572 }1573 });1574 api.controlConstructor.themify_margin = api.ThemifyMargin;1575 ////////////////////////////////////////////////////////////////////////////1576 // Margin Control End1577 ////////////////////////////////////////////////////////////////////////////1578 ////////////////////////////////////////////////////////////////////////////1579 // Padding Control Start1580 ////////////////////////////////////////////////////////////////////////////1581 api.ThemifyPadding = api.ThemifyMargin.extend({1582 field: '.themify_padding_control'1583 });1584 api.controlConstructor.themify_padding = api.ThemifyPadding;1585 ////////////////////////////////////////////////////////////////////////////1586 // Padding Control End1587 ////////////////////////////////////////////////////////////////////////////1588 ////////////////////////////////////////////////////////////////////////////1589 // Width Control Start1590 ////////////////////////////////////////////////////////////////////////////1591 api.ThemifyWidth = api.ThemifyControl.extend({1592 field: '.themify_width_control',1593 ready: function () {1594 var control = this,1595 $field = $(control.field, control.container);1596 if ($field.val()) {1597 control.value[control.id] = parseJSON($field.val());1598 } else {1599 control.value[control.id] = {1600 'width': '',1601 'unit': 'px',1602 'auto': ''1603 };1604 }1605 // Width width1606 control.dimension($('.dimension-width', control.container));1607 // Width unit1608 control.dropdown($('.dimension-unit', control.container), 'unit');1609 // Auto1610 control.auto($('.auto-prop', control.container));1611 }1612 });1613 api.controlConstructor.themify_width = api.ThemifyWidth;1614 ////////////////////////////////////////////////////////////////////////////1615 // Width Control End1616 ////////////////////////////////////////////////////////////////////////////1617 ////////////////////////////////////////////////////////////////////////////1618 // Height Control Start1619 ////////////////////////////////////////////////////////////////////////////1620 api.ThemifyHeight = api.ThemifyWidth.extend({1621 field: '.themify_height_control'1622 });1623 api.controlConstructor.themify_height = api.ThemifyHeight;1624 ////////////////////////////////////////////////////////////////////////////1625 // Height Control End1626 ////////////////////////////////////////////////////////////////////////////1627 ////////////////////////////////////////////////////////////////////////////1628 // Position Control Start1629 ////////////////////////////////////////////////////////////////////////////1630 api.ThemifyPosition = api.ThemifyControl.extend({1631 field: '.themify_position_control',1632 dropdownPosition: function ($obj, key) {1633 var control = this, $field = $(control.field, control.container),1634 initial = $obj.find('option:selected').val();1635 $obj.on('change', function () {1636 var $select = $(this), value = $('option:selected', $select).val();1637 control.value[control.id][key] = value;1638 $field.val(JSON.stringify(control.value[control.id])).trigger('change');1639 if (value && 'static' !== value) {1640 $select.closest('.themify-customizer-brick').parent().find('.position-wrap').show();1641 } else {1642 $select.closest('.themify-customizer-brick').parent().find('.position-wrap').hide();1643 }1644 });1645 if (initial && 'static' !== initial) {1646 $obj.closest('.themify-customizer-brick').parent().find('.position-wrap').show();1647 } else {1648 $obj.closest('.themify-customizer-brick').parent().find('.position-wrap').hide();1649 }1650 },1651 ready: function () {1652 var control = this,1653 $field = $(control.field, control.container);1654 control.value[control.id] = $field.val() ? parseJSON($field.val()) : {'position': ''};1655 // Position1656 control.dropdownPosition($('.position', control.container), 'position');1657 // Position value1658 control.dimensionSame($('.dimension-width', control.container));1659 // Position unit1660 control.dropdownSame($('.dimension-unit', control.container), 'unit');1661 // Auto1662 control.autoSame($('.auto-prop', control.container));1663 }1664 });1665 api.controlConstructor.themify_position = api.ThemifyPosition;1666 ////////////////////////////////////////////////////////////////////////////1667 // Position Control End1668 ////////////////////////////////////////////////////////////////////////////1669 ////////////////////////////////////////////////////////////////////////////1670 // CustomCSS Control Start1671 ////////////////////////////////////////////////////////////////////////////1672 api.ThemifyCustomCSS = api.ThemifyControl.extend({1673 field: '.themify_customcss_control',1674 expand: function (container) {1675 $('.themify-expand', container.container).on('click', function (e) {1676 e.preventDefault();1677 container.editor.codemirror.setOption('fullScreen', true);1678 $('.close-custom-css-expanded').addClass('enable-expanded-area');1679 $('.close-custom-css-expanded').on('click', function(){1680 container.editor.codemirror.setOption('fullScreen', false);1681 $('.close-custom-css-expanded').removeClass('enable-expanded-area')1682 })1683 });1684 },1685 ready: function () {1686 var control = this,1687 $field = $( control.field, control.container ),1688 $customCSS = $( '.customcss', control.container );1689 control.value[control.id] = $field.data('value') ? window.atob( $field.data( 'value' ) ) : '';1690 $field.data( 'value', '' );1691 $field.val( control.value[control.id] );1692 1693 control.initSyntaxHighlightingEditor();1694 1695 // Prevent scroll to top1696 var currentVal = typeof control.editor !== 'undefined'1697 ? control.editor.codemirror.getValue()1698 : control.container.find('textarea').val();1699 // Initialize expand/contract action1700 control.expand( control, $customCSS );1701 },1702 initSyntaxHighlightingEditor: function( context ) {1703 if ( typeof wp.codeEditor === 'undefined' ) return;1704 var control = this, $textarea, settings, suspendEditorUpdate = false;1705 $textarea = context ? context.find( 'textarea' ) : control.container.find( 'textarea' );1706 settings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};1707 settings.codemirror = _.extend( {}, settings.codemirror, { indentUnit: 2, tabSize: 2, mode: 'css' } );1708 control.editor = wp.codeEditor.initialize( $textarea, settings );1709 // Improve the editor accessibility.1710 $( control.editor.codemirror.display.lineDiv )1711 .attr({1712 role: 'textbox',1713 'aria-multiline': 'true',1714 'aria-label': control.params.label,1715 'aria-describedby': 'editor-keyboard-trap-help-1 editor-keyboard-trap-help-2 editor-keyboard-trap-help-3 editor-keyboard-trap-help-4'1716 });1717 /*1718 * When the CodeMirror instance changes, mirror to the textarea,1719 * where we have our "true" change event handler bound.1720 */1721 control.editor.codemirror.on( 'change', function( codemirror ) {1722 suspendEditorUpdate = true;1723 control.container.find( 'textarea' ).val( codemirror.getValue() ).trigger( 'change' );1724 suspendEditorUpdate = false;1725 });1726 control.editor.codemirror.on( 'keydown', function onKeydown( codemirror, event ) {1727 27 == event.keyCode && event.stopPropagation();1728 });1729 },1730 });1731 api.controlConstructor.themify_customcss = api.ThemifyCustomCSS;1732 ////////////////////////////////////////////////////////////////////////////1733 // CustomCSS Control End1734 ////////////////////////////////////////////////////////////////////////////1735 ////////////////////////////////////////////////////////////////////////////1736 // Image Select Control Start1737 ////////////////////////////////////////////////////////////////////////////1738 api.ThemifyImageSelect = api.ThemifyControl.extend({1739 field: '.themify_image_select_control',1740 ready: function () {1741 var control = this, $field = $(control.field, control.container);1742 if ($field.val()) {1743 control.value[control.id] = parseJSON($field.val());1744 } else {1745 control.value[control.id] = {1746 'type': '',1747 'selected': ''1748 };1749 }1750 $('.image-select', control.container).on('click', function (e) {1751 e.preventDefault();1752 control.value[control.id].selected = $(this).data('option');1753 $field.val(JSON.stringify(control.value[control.id])).trigger('change');1754 });1755 }1756 });1757 api.controlConstructor.themify_image_select = api.ThemifyImageSelect;1758 ////////////////////////////////////////////////////////////////////////////1759 // Image Select Control End1760 ////////////////////////////////////////////////////////////////////////////1761 ////////////////////////////////////////////////////////////////////////////1762 // Tools Control Start1763 ////////////////////////////////////////////////////////////////////////////1764 api.ThemifyTools = api.ThemifyControl.extend({1765 field: '.themify_tools_control',1766 clearing: false,1767 saveOptionCallback: function () {1768 // Save and reload1769 $('#customize-header-actions').find('.save').trigger('click');1770 },1771 ready: function () {1772 var control = this;1773 1774 ////////////////////////////////////////////////////////////////////////////1775 // Clear Tool Start1776 ////////////////////////////////////////////////////////////////////////////1777 api.bind('saved', function () {1778 if (api.ThemifyTools.field) {1779 if ( 'true' === control.getParameterByName('cleared') ) {1780 window.location.reload();1781 } else {1782 var hashlink = control.addQueryArg('cleared', 'true', (window.top.location.href));1783 hashlink = (hashlink[hashlink.length-1] == '#') ? hashlink.replace('#' , '') : hashlink;1784 console.log(hashlink);1785 window.top.location = hashlink;1786 }1787 api.ThemifyTools.field = false;1788 }1789 });1790 $('.clearall', control.container).on('click', function () {1791 if (window.confirm(themifyCustomizerControls.clearMessage)) {1792 // Tell the event hooked to 'saved' that we want to reload.1793 api.ThemifyTools.field = true;1794 // Clear all option fields1795 $('.themify-customizer-value-field').each(function () {1796 $(this).val('').trigger('change');1797 });1798 // Clear the preview stylesheet1799 api.previewer.send('themify-customize-clearall');1800 // Restore site name1801 var sessionSiteName = $('.customize-control-themify_logo').find('.site-name').val(),1802 sessionTagline = $('.customize-control-themify_tagline').find('.site-name').val(),1803 currentSiteName = $(this).data('sitename'),1804 currentTagline = $(this).data('tagline');1805 if (sessionSiteName != currentSiteName || sessionTagline != currentTagline) {1806 // Save will be triggered once the option saving succeeds1807 control.saveOption('blogname', currentSiteName);1808 control.saveOption('blogdescription', currentTagline);1809 } else {1810 // Trigger save button manually1811 control.saveOptionCallback();1812 }1813 }1814 });1815 1816 ////////////////////////////////////////////////////////////////////////////1817 // Clear Tool End1818 ////////////////////////////////////////////////////////////////////////////1819 1820 ////////////////////////////////////////////////////////////////////////////1821 // Export Tool Start1822 ////////////////////////////////////////////////////////////////////////////1823 1824 $('.customize-export', control.container).on('click', function (e) {1825 if($('#customize-header-actions').find('.save').val() != 'Published'){1826 if (!window.confirm(themifyCustomizerControls.exportMessage)) {1827 e.preventDefault();1828 }1829 }1830 });1831 1832 ////////////////////////////////////////////////////////////////////////////1833 // Export Tool End1834 ////////////////////////////////////////////////////////////////////////////1835 }1836 });1837 api.controlConstructor.themify_tools = api.ThemifyTools;1838 ////////////////////////////////////////////////////////////////////////////1839 // Tools Control End1840 ////////////////////////////////////////////////////////////////////////////1841 // Responsive Switcher Helper1842 function themifyResponsiveHelper() {1843 var buttons = '#customize-footer-actions .devices button', width, css;1844 $( 'body' ).on( 'click', buttons, function() {1845 var device = $( this ).data( 'device' ),1846 preview = $( '#customize-preview' );1847 if( typeof themifyCustomizerControls.responsiveBreakpoints === 'object'1848 && ( width = themifyCustomizerControls.responsiveBreakpoints[ device ] ) ) {1849 if ( device === 'tablet_landscape' ) width = 976; // use this value for preview only1850 css = {1851 width: width + 'px',1852 marginLeft: -width / 21853 };1854 } else {1855 css = { width: '', marginLeft: '' };1856 }1857 preview.css( css );1858 } );1859 }1860 1861 themifyResponsiveHelper();1862 // Mobile Menu Customizer1863 /* when closing the Mobile Menu accordion, close the sidemenu panel automatically */1864 $( 'body' ).on( 'click', '#customize-control-start_mobile_menu_acc_ctrl:not(.topen) > .themify-suba-toggle', function ( e ) {1865 var menuPreview = $('#customize-preview > iframe')[0].contentWindow;1866 menuPreview.jQuery('#menu-icon').themifySideMenu( 'hide' );1867 } )1868 /* when Mobile Menu toggle is opened, show the sidemenu panel, activate the Desktop breakpoint and resize the preview window */1869 .on( 'click', '#customize-control-start_mobile_menu_acc_ctrl.topen > .themify-suba-toggle', function ( e ) {1870 var menuPreview = $('#customize-preview > iframe')[0].contentWindow;1871 $('#customize-footer-actions .preview-desktop').click();1872 // wait 1 second for resizing to desktop to finish1873 setTimeout( function(){1874 if( $( '#customize-preview' ).width() > themifyCustomizerControls.mobile_menu_trigger_point ) {1875 $( '#customize-preview' ).css( {1876 width: themifyCustomizerControls.mobile_menu_trigger_point + 'px',1877 marginLeft: ( $( '#customize-preview' ).width() - themifyCustomizerControls.mobile_menu_trigger_point ) / 21878 } );1879 }1880 menuPreview.jQuery('#menu-icon').themifySideMenu( 'show' );1881 }, 1000 );1882 })1883 /* when switching to a breakpoint other than desktop, close the Mobile Menu settings */1884 .on( 'click', '#customize-footer-actions button', function(){1885 if( ! $( this ).hasClass( 'preview-desktop' ) ) {1886 $( '#customize-control-start_mobile_menu_acc_ctrl.topen .themify-suba-toggle' ).click();1887 }1888 } );...
Reg.WebControls.Search.js
Source:Reg.WebControls.Search.js
1/// <reference path="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\MicrosoftAjax.debug.js" />2/// <reference path="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\jquery-1.7.2-vsdoc.js" />3var SearchControls = {4 Control: 'Control',5 TextField: 'TextField',6 SelectField: 'SelectField',7 DateRange: 'DateRange'8};9function createControl(containerId) {10 var _val = '';11 var control = {12 type: 'Control',13 toString: function () {14 return this.type;15 },16 val: function (value) {17 if (value !== undefined) {18 _val = value;19 }20 else {21 return _val;22 }23 },24 reset: function () {25 this.val('');26 },27 isEmpty: function () {28 return this.val() === '';29 },30 jContainer: resolveContainerId(containerId),31 container: null,32 jElement: $([]),33 element: null34 };35 control.container = control.jContainer[0];36 return control;37}38function createFreetextField(containerId) {39 var control = createControl(containerId);40 control.type = 'Freetext';41 control.jElement = $('#' + containerId);42 control.element = control.jElement[0];43 control.val = function (value) {44 if (value !== undefined) {45 control.element.value = value;46 control.jElement.focus();47 }48 else {49 return control.element.value;50 }51 };52 return control;53}54function createTextField(containerId) {55 56 var control = createControl(containerId);57 control.type = 'TextField';58 var html = '<input type="text" class="searchControl searchControlTextField" />';59 60 (function render () {61 control.jElement = control.jContainer.append(html).children().last();62 control.element = control.jElement[0];63 })();64 control.val = function (value) {65 if (value !== undefined) {66 control.element.value = value;67 }68 else {69 return control.element.value;70 }71 };72 return control;73}74function createSelectField(containerId) {75 var control = createControl(containerId);76 control.type = 'SelectField';77 var html = '<select class="searchControl searchControlSelectField"><option></option></select>';78 (function render() {79 control.jElement = control.jContainer.append(html).children().last();80 control.element = control.jElement[0];81 })();82 control.val = function (value) {83 var opts = control.element.options;84 if (value !== undefined) {85 for (var i = 0; i < opts.length; i++) {86 if (opts[i].value == value) {87 opts[i].selected = true;88 break;89 }90 }91 }92 else {93 return opts[control.element.selectedIndex].text;94 }95 };96 control.reset = function () {97 control.selected(0);98 };99 control.options = control.element.options;100 control.addOption = function (display, value) {101 if (!value) {102 value = display;103 }104 control.element.options.add(new Option(display, value));105 };106 control.selected = function (valdex) {107 var opts = control.element.options;108 if (valdex !== undefined) {109 if (isInt(valdex)) {110 opts[valdex].selected = true;111 }112 else {113 for (var i = 0; i < opts.length; i++) {114 if (opts[i].text == valdex) {115 opts[i].selected = true;116 break;117 }118 }119 }120 }121 else {122 return opts[control.element.selectedIndex].text;123 }124 };125 function isInt(n) {126 return n % 1 === 0;127 }128 return control;129}130function createDaterangeField(containerId) {131 var control = createControl(containerId);132 control.type = 'DateRange';133 var jTextOne = $([]);134 var jTextTwo = $([]);135 var html = '<table class="searchControl searchControlDaterangeField"> \136 <tr> \137 <td> \138 <input type="text" class="searchControlDateText" /> \139 </td> \140 <td> \141 To \142 </td> \143 <td align="right"> \144 <input type="text" class="searchControlDateText" /> \145 </td> \146 </tr> \147 </table>';148 (function render() {149 control.jElement = control.jContainer.append(html).children().last();150 control.element = control.jElement[0];151 $('.searchControlDateText').datepicker({152 showOn: "button",153 buttonImage: "/sites/Imaging/Style%20Library/RegalNetBranding/Images/KLCalendar20.png",154 buttonImageOnly: true,155 buttonText: "Select date"156 });157 jTextOne = $('TD:nth-child(1)>INPUT', control.element);158 jTextTwo = $('TD:nth-child(3)>INPUT', control.element);159 })();160 control.reset = function () {161 control.val(';');162 };163 control.val = function (value) {164 if (value !== undefined) {165 var vals = value.split(';');166 control.val1(vals[0]);167 control.val2(vals[1]);168 }169 else {170 return control.val1() + ';' + control.val2();171 }172 };173 control.val1 = function (value) {174 if (value !== undefined) {175 jTextOne.val(value);176 }177 else {178 return jTextOne.val();179 }180 };181 control.val2 = function (value) {182 if (value !== undefined) {183 jTextTwo.val(value);184 }185 else {186 return jTextTwo.val();187 }188 };189 control.isEmpty = function () {190 return control.val() === ';';191 }192 return control;193}194function resolveContainerId(containerId) {195 if (typeof containerId == 'object') {196 return containerId;197 }198 else {199 return $('#' + containerId);200 }...
controls.js
Source:controls.js
...52};53const initBlogPageFocus = () => {54 wp.customize.section( 'neve_blog_archive_layout', ( section ) => {55 section.expanded.bind( ( isExpanded ) => {56 const front = wp.customize.control( 'show_on_front' ).setting();57 let pageId = '';58 if ( front === 'page' ) {59 pageId = wp.customize.control( 'page_for_posts' ).setting();60 }61 if ( isExpanded ) {62 wp.customize.previewer.previewUrl.set(63 pageId ? `/?page_id=${ pageId }` : '/'64 );65 }66 } );67 } );68};69domReady( () => {70 initDeviceSwitchers();71 initBlogPageFocus();72} );73wp.customize.bind( 'ready', () => {74 initDynamicFields();75} );76window.HFG = {77 getSettings: () => {78 const usedSettings = {};79 NeveReactCustomize.headerControls.map( ( item ) => {80 if ( ! wp.customize.control( item ) ) return false;81 usedSettings[ item ] = wp.customize.control( item ).setting.get();82 } );83 return JSON.stringify( usedSettings );84 },...
index.js
Source:index.js
...41window.HFG = {42 getSettings: () => {43 const usedSettings = {}44 NeveReactCustomize.headerControls.map( (item) => {45 if ( !wp.customize.control( item ) ) return false46 usedSettings[item] = wp.customize.control( item ).setting.get()47 } )48 return JSON.stringify( usedSettings )49 }...
Using AI Code Generation
1describe('Controller: MainCtrl', function () {2 beforeEach(module('angularApp'));3 scope;4 beforeEach(inject(function ($controller, $rootScope) {5 scope = $rootScope.$new();6 MainCtrl = $controller('MainCtrl', {7 });8 }));9 it('should attach a list of awesomeThings to the scope', function () {10 expect(scope.awesomeThings.length).toBe(3);11 });12});13'use strict';14angular.module('angularApp')15 .controller('MainCtrl', function ($scope) {16 ];17 });
Using AI Code Generation
1describe('test', function() {2 beforeEach(module('test'));3 var $scope;4 beforeEach(inject(function($rootScope, $controller) {5 $scope = $rootScope.$new();6 $controller('test', {$scope: $scope});7 }));8 it('should do something', function() {9 expect($scope.test).toBeDefined();10 });11});12 <div ng-click="test()"></div>13describe('test', function() {14 beforeEach(module('test'));15 var $scope;16 beforeEach(inject(function($rootScope, $compile) {17 $scope = $rootScope.$new();18 $compile('<div ng-controller="test"><div ng-click="test()"></div></div>')($scope);19 $scope.$digest();20 }));21 it('should do something', function() {22 expect($scope.test).toBeDefined();23 });24});25 <div ng-click="test()"></div>26describe('test', function() {27 beforeEach(module('test'));28 var $scope;29 beforeEach(inject(function($rootScope, $compile) {30 $scope = $rootScope.$new();31 $compile('<div ng-controller="test"><div ng-click="test()"></div></div>')($scope);32 $scope.$digest();33 }));34 it('should do something', function() {35 expect($scope.test).toBeDefined();36 });37});38 <div ng-click="test()"></div>39describe('test', function() {40 beforeEach(module('test'));41 var $scope;42 beforeEach(inject(function($rootScope, $compile) {43 $scope = $rootScope.$new();44 $compile('<div ng-controller="test"><div ng-click="test()"></div></div>')($scope);45 $scope.$digest();46 }));47 it('should do something', function
Using AI Code Generation
1var ngMocks = require('ng-mocks');2var myModule = require('./myModule');3describe('myModule', function () {4 beforeEach(function () {5 ngMocks.module(myModule.name);6 });7 it('should have a controller', function () {8 var ctrl = ngMocks.inject(function ($controller) {9 return $controller('myController');10 });11 expect(ctrl).toBeDefined();12 });13});14angular.module('myModule', [])15 .controller('myController', function () {16 });17var ngMocks = require('ng-mocks');18var myModule = require('./myModule');19describe('myModule', function () {20 beforeEach(function () {21 ngMocks.module(myModule.name, 'myModule.controllers');22 });23});24angular.module('myModule', ['myModule.controllers'])25 .controller('myController', function () {26 });27angular.module('myModule.controllers', [])28 .controller('myController', function () {29 });
Using AI Code Generation
1describe('myController', function() {2 var $scope, $controller;3 beforeEach(function() {4 module('myModule');5 inject(function(_$controller_) {6 $controller = _$controller_;7 });8 });9 describe('$scope.add()', function() {10 it('should add two numbers correctly', function() {11 var $scope = {};12 var controller = $controller('myController', { $scope: $scope });13 $scope.x = 1;14 $scope.y = 2;15 $scope.add();16 expect($scope.z).toBe(3);17 });18 });19});20angular.module('myModule', [])21 .controller('myController', function($scope) {22 $scope.add = function() {23 $scope.z = $scope.x + $scope.y;24 };25 });
Using AI Code Generation
1var ngMock = require('ng-mocks');2ngMock.control({3 controller: function($scope) {4 this.test = 'test';5 }6});7var ngMock = require('ng-mocks');8ngMock.inject(function($controller) {9 var scope = {};10 var ctrl = $controller('MyController', {11 });12 console.log(ctrl.test);13});14var ngMock = require('ng-mocks');15ngMock.mock({16 provider: function() {17 return {18 $get: function() {19 return {20 };21 }22 };23 }24});25var ngMock = require('ng-mocks');26ngMock.mock({27 provider: function() {28 return {29 $get: function() {30 return {31 };32 }33 };34 }35});36var ngMock = require('ng-mocks');37ngMock.mock({38 provider: function() {39 return {40 $get: function() {41 return {42 };43 }44 };45 }46});47var ngMock = require('ng-mocks');48ngMock.mock({49 provider: function() {50 return {51 $get: function() {52 return {53 };54 }55 };56 }57});58var ngMock = require('ng-mocks');59ngMock.mock({60 provider: function() {61 return {62 $get: function() {63 return {64 };65 }66 };67 }68});
Using AI Code Generation
1describe('Test', function () {2 beforeEach(module('myModule'));3 it('should test', inject(function (myService) {4 }));5});6describe('Test', function () {7 beforeEach(module('myModule'));8 it('should test', inject(function ($injector) {9 var myService = $injector.invoke(function (myService) {10 return myService;11 });12 }));13});14describe('Test', function () {15 beforeEach(module('myModule'));16 it('should test', inject(function ($injector) {17 var myService = $injector.invoke(function (myService) {18 return myService;19 });20 }));21});22describe('Test', function () {23 beforeEach(module('myModule'));24 it('should test', inject(function ($injector) {25 var myService = $injector.invoke(function (myService) {26 return myService;27 });28 }));29});30describe('Test', function () {31 beforeEach(module('myModule'));32 it('should test', inject(function ($injector) {33 var myService = $injector.invoke(function (myService) {34 return myService;35 });36 }));37});
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!