[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/guidersjs/ -> guiders-1.2.6.js (source)

   1  /**
   2   * guiders.js
   3   *
   4   * version 1.2.6
   5   *
   6   * Developed at Optimizely. (www.optimizely.com)
   7   * We make A/B testing you'll actually use.
   8   *
   9   * Released under the Apache License 2.0.
  10   * www.apache.org/licenses/LICENSE-2.0.html
  11   *
  12   * Questions about Guiders?
  13   * You may email me (Jeff Pickhardt) at [email protected]
  14   *
  15   * Questions about Optimizely should be sent to:
  16   * [email protected] or [email protected]
  17   *
  18   * Enjoy!
  19   */
  20  
  21  var guiders = (function($) {
  22    var guiders = {};
  23    
  24    guiders.version = "1.2.6";
  25  
  26    guiders._defaultSettings = {
  27      attachTo: null, // Selector of the element to attach to.
  28      autoFocus: false, // Determines whether or not the browser scrolls to the element.
  29      buttons: [{name: "Close"}],
  30      buttonCustomHTML: "",
  31      classString: null,
  32      description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  33      highlight: null,
  34      isHashable: true,
  35      offset: {
  36          top: null,
  37          left: null
  38      },
  39      onShow: null,
  40      onHide: null,
  41      overlay: false,
  42      position: 0, // 1-12 follows an analog clock, 0 means centered.
  43      title: "Sample title goes here",
  44      width: 400,
  45      xButton: false // This places a closer "x" button in the top right of the guider.
  46    };
  47  
  48    guiders._htmlSkeleton = [
  49      "<div class='guider'>",
  50      "  <div class='guider_content'>",
  51      "    <div class='guider_close'></div>",
  52      "    <h1 class='guider_title'></h1>",
  53      "    <p class='guider_description'></p>",
  54      "    <div class='guider_buttons'>",
  55      "    </div>",
  56      "  </div>",
  57      "  <div class='guider_arrow'>",
  58      "  </div>",
  59      "</div>"
  60    ].join("");
  61  
  62    guiders._arrowSize = 42; // This is the arrow's width and height.
  63    guiders._buttonElement = "<a></a>";
  64    guiders._buttonAttributes = {"href": "javascript:void(0);"};
  65    guiders._closeButtonTitle = "Close";
  66    guiders._currentGuiderID = null;
  67    guiders._guiders = {};
  68    guiders._lastCreatedGuiderID = null;
  69    guiders._nextButtonTitle = "Next";
  70    guiders._offsetNameMapping = {
  71      "topLeft": 11,
  72      "top": 12,
  73      "topRight": 1,
  74      "rightTop": 2,
  75      "right": 3,
  76      "rightBottom": 4,
  77      "bottomRight": 5,
  78      "bottom": 6,
  79      "bottomLeft": 7,
  80      "leftBottom": 8,
  81      "left": 9,
  82      "leftTop": 10
  83    };
  84    guiders._windowHeight = 0;
  85  
  86    guiders._addButtons = function(myGuider) {
  87      var guiderButtonsContainer = myGuider.elem.find(".guider_buttons");
  88    
  89      if (myGuider.buttons === null || myGuider.buttons.length === 0) {
  90        guiderButtonsContainer.remove();
  91        return;
  92      }
  93    
  94      for (var i = myGuider.buttons.length - 1; i >= 0; i--) {
  95        var thisButton = myGuider.buttons[i];
  96        var thisButtonElem = $(guiders._buttonElement, $.extend({
  97                                                           "class" : "guider_button",
  98                                                            "html" : thisButton.name },
  99                                                          guiders._buttonAttributes, thisButton.html || {}));
 100  
 101        if (typeof thisButton.classString !== "undefined" && thisButton.classString !== null) {
 102          thisButtonElem.addClass(thisButton.classString);
 103        }
 104    
 105        guiderButtonsContainer.append(thisButtonElem);
 106    
 107        if (thisButton.onclick) {
 108          thisButtonElem.bind("click", thisButton.onclick);
 109        } else if (!thisButton.onclick &&
 110                   thisButton.name.toLowerCase() === guiders._closeButtonTitle.toLowerCase()) { 
 111          thisButtonElem.bind("click", function() { guiders.hideAll(); });
 112        } else if (!thisButton.onclick &&
 113                   thisButton.name.toLowerCase() === guiders._nextButtonTitle.toLowerCase()) { 
 114          thisButtonElem.bind("click", function() { !myGuider.elem.data('locked') && guiders.next(); });
 115        }
 116      }
 117    
 118      if (myGuider.buttonCustomHTML !== "") {
 119        var myCustomHTML = $(myGuider.buttonCustomHTML);
 120        myGuider.elem.find(".guider_buttons").append(myCustomHTML);
 121      }
 122    
 123      if (myGuider.buttons.length === 0) {
 124        guiderButtonsContainer.remove();
 125      }
 126    };
 127  
 128    guiders._addXButton = function(myGuider) {
 129        var xButtonContainer = myGuider.elem.find(".guider_close");
 130        var xButton = $("<div></div>", {
 131                        "class" : "x_button",
 132                        "role" : "button" });
 133        xButtonContainer.append(xButton);
 134        xButton.click(function() { guiders.hideAll(); });
 135    };
 136  
 137    guiders._attach = function(myGuider) {
 138      if (typeof myGuider !== 'object') {
 139        return;
 140      }
 141          
 142      var attachTo = $(myGuider.attachTo);
 143  
 144      var myHeight = myGuider.elem.innerHeight();
 145      var myWidth = myGuider.elem.innerWidth();
 146  
 147      if (myGuider.position === 0 || attachTo.length === 0) {
 148        // The guider is positioned in the center of the screen.
 149        myGuider.elem.css("position", "fixed");
 150        myGuider.elem.css("top", ($(window).height() - myHeight) / 3 + "px");
 151        myGuider.elem.css("left", ($(window).width() - myWidth) / 2 + "px");
 152        return;
 153      }
 154      
 155      // Otherwise, the guider is positioned relative to the attachTo element.
 156      var base = attachTo.offset();
 157      var top = base.top;
 158      var left = base.left;
 159      
 160      // topMarginOfBody corrects positioning if body has a top margin set on it.
 161      var topMarginOfBody = $("body").outerHeight(true) - $("body").outerHeight(false);
 162      base -= topMarginOfBody;
 163  
 164      // Now, take into account how the guider should be positioned relative to the attachTo element.
 165      // e.g. top left, bottom center, etc.
 166      if (guiders._offsetNameMapping[myGuider.position]) {
 167        // As an alternative to the clock model, you can also use keywords to position the guider.
 168        myGuider.position = guiders._offsetNameMapping[myGuider.position];
 169      }
 170      
 171      var attachToHeight = attachTo.innerHeight();
 172      var attachToWidth = attachTo.innerWidth();  
 173      var bufferOffset = 0.9 * guiders._arrowSize;
 174      
 175      // offsetMap follows the form: [height, width]
 176      var offsetMap = {
 177        1: [-bufferOffset - myHeight, attachToWidth - myWidth],
 178        2: [0, bufferOffset + attachToWidth],
 179        3: [attachToHeight/2 - myHeight/2, bufferOffset + attachToWidth],
 180        4: [attachToHeight - myHeight, bufferOffset + attachToWidth],
 181        5: [bufferOffset + attachToHeight, attachToWidth - myWidth],
 182        6: [bufferOffset + attachToHeight, attachToWidth/2 - myWidth/2],
 183        7: [bufferOffset + attachToHeight, 0],
 184        8: [attachToHeight - myHeight, -myWidth - bufferOffset],
 185        9: [attachToHeight/2 - myHeight/2, -myWidth - bufferOffset],
 186        10: [0, -myWidth - bufferOffset],
 187        11: [-bufferOffset - myHeight, 0],
 188        12: [-bufferOffset - myHeight, attachToWidth/2 - myWidth/2]
 189      };
 190      var offset = offsetMap[myGuider.position];
 191      top   += offset[0];
 192      left  += offset[1];
 193      
 194      var positionType = "absolute";
 195      // If the element you are attaching to is position: fixed, then we will make the guider
 196      // position: fixed as well.
 197      if (attachTo.css("position") == "fixed") {
 198        positionType = "fixed";
 199        top -= $(window).scrollTop();
 200        left -= $(window).scrollLeft();
 201      }
 202      
 203      // If you specify an additional offset parameter when you create the guider, it gets added here.
 204      if (myGuider.offset.top !== null) {
 205        top += myGuider.offset.top;
 206      }
 207      if (myGuider.offset.left !== null) {
 208        left += myGuider.offset.left;
 209      }
 210      
 211      // Finally, set the style of the guider and return it!
 212      return myGuider.elem.css({
 213        "position": positionType,
 214        "top": top,
 215        "left": left
 216      });
 217    };
 218  
 219    guiders._guiderById = function(id) {
 220      if (typeof guiders._guiders[id] === "undefined") {
 221        throw "Cannot find guider with id " + id;
 222      }
 223      return guiders._guiders[id];
 224    };
 225  
 226    guiders._showOverlay = function() {
 227      $("#guider_overlay").fadeIn("fast", function(){
 228        if (this.style.removeAttribute) {
 229          this.style.removeAttribute("filter");
 230        }
 231      });
 232      // This callback is needed to fix an IE opacity bug.
 233      // See also:
 234      // http://www.kevinleary.net/jquery-fadein-fadeout-problems-in-internet-explorer/
 235    };
 236  
 237    guiders._highlightElement = function(selector) {
 238      $(selector).addClass('guider_highlight');
 239    };
 240  
 241    guiders._dehighlightElement = function(selector) {
 242      $(selector).removeClass('guider_highlight');
 243    };
 244  
 245    guiders._hideOverlay = function() {
 246      $("#guider_overlay").fadeOut("fast");
 247    };
 248  
 249    guiders._initializeOverlay = function() {
 250      if ($("#guider_overlay").length === 0) {
 251        $("<div id=\"guider_overlay\"></div>").hide().appendTo("body");
 252      }
 253    };
 254  
 255    guiders._styleArrow = function(myGuider) {
 256      var position = myGuider.position || 0;
 257      if (!position) {
 258        return;
 259      }
 260      var myGuiderArrow = $(myGuider.elem.find(".guider_arrow"));
 261      var newClass = {
 262        1: "guider_arrow_down",
 263        2: "guider_arrow_left",
 264        3: "guider_arrow_left",
 265        4: "guider_arrow_left",
 266        5: "guider_arrow_up",
 267        6: "guider_arrow_up",
 268        7: "guider_arrow_up",
 269        8: "guider_arrow_right",
 270        9: "guider_arrow_right",
 271        10: "guider_arrow_right",
 272        11: "guider_arrow_down",
 273        12: "guider_arrow_down"
 274      };
 275      myGuiderArrow.addClass(newClass[position]);
 276    
 277      var myHeight = myGuider.elem.innerHeight();
 278      var myWidth = myGuider.elem.innerWidth();
 279      var arrowOffset = guiders._arrowSize / 2;
 280      var positionMap = {
 281        1: ["right", arrowOffset],
 282        2: ["top", arrowOffset],
 283        3: ["top", myHeight/2 - arrowOffset],
 284        4: ["bottom", arrowOffset],
 285        5: ["right", arrowOffset],
 286        6: ["left", myWidth/2 - arrowOffset],
 287        7: ["left", arrowOffset],
 288        8: ["bottom", arrowOffset],
 289        9: ["top", myHeight/2 - arrowOffset],
 290        10: ["top", arrowOffset],
 291        11: ["left", arrowOffset],
 292        12: ["left", myWidth/2 - arrowOffset]
 293      };
 294      var position = positionMap[myGuider.position];
 295      myGuiderArrow.css(position[0], position[1] + "px");
 296    };
 297  
 298    /**
 299     * One way to show a guider to new users is to direct new users to a URL such as
 300     * http://www.mysite.com/myapp#guider=welcome
 301     *
 302     * This can also be used to run guiders on multiple pages, by redirecting from
 303     * one page to another, with the guider id in the hash tag.
 304     *
 305     * Alternatively, if you use a session variable or flash messages after sign up,
 306     * you can add selectively add JavaScript to the page: "guiders.show('first');"
 307     */
 308    guiders._showIfHashed = function(myGuider) {
 309      var GUIDER_HASH_TAG = "guider=";
 310      var hashIndex = window.location.hash.indexOf(GUIDER_HASH_TAG);
 311      if (hashIndex !== -1) {
 312        var hashGuiderId = window.location.hash.substr(hashIndex + GUIDER_HASH_TAG.length);
 313        if (myGuider.id.toLowerCase() === hashGuiderId.toLowerCase()) {
 314          // Success!
 315          guiders.show(myGuider.id);
 316        }
 317      }
 318    };
 319  
 320    guiders.reposition = function() {
 321      var currentGuider = guiders._guiders[guiders._currentGuiderID];
 322      guiders._attach(currentGuider);
 323    };
 324    
 325    guiders.next = function() {
 326      var currentGuider = guiders._guiders[guiders._currentGuiderID];
 327      if (typeof currentGuider === "undefined") {
 328        return;
 329      }
 330      currentGuider.elem.data('locked', true);
 331  
 332      var nextGuiderId = currentGuider.next || null;
 333      if (nextGuiderId !== null && nextGuiderId !== "") {
 334        var myGuider = guiders._guiderById(nextGuiderId);
 335        var omitHidingOverlay = myGuider.overlay ? true : false;
 336        guiders.hideAll(omitHidingOverlay, true);
 337        if (currentGuider && currentGuider.highlight) {
 338            guiders._dehighlightElement(currentGuider.highlight);
 339        }
 340        guiders.show(nextGuiderId);
 341      }
 342    };
 343  
 344    guiders.createGuider = function(passedSettings) {
 345      if (passedSettings === null || passedSettings === undefined) {
 346        passedSettings = {};
 347      }
 348      
 349      // Extend those settings with passedSettings
 350      myGuider = $.extend({}, guiders._defaultSettings, passedSettings);
 351      myGuider.id = myGuider.id || String(Math.floor(Math.random() * 1000));
 352      
 353      var guiderElement = $(guiders._htmlSkeleton);
 354      myGuider.elem = guiderElement;
 355      if (typeof myGuider.classString !== "undefined" && myGuider.classString !== null) {
 356        myGuider.elem.addClass(myGuider.classString);
 357      }
 358      myGuider.elem.css("width", myGuider.width + "px");
 359      
 360      var guiderTitleContainer = guiderElement.find(".guider_title");
 361      guiderTitleContainer.html(myGuider.title);
 362      
 363      guiderElement.find(".guider_description").html(myGuider.description);
 364      
 365      guiders._addButtons(myGuider);
 366      
 367      if (myGuider.xButton) {
 368          guiders._addXButton(myGuider);
 369      }
 370      
 371      guiderElement.hide();
 372      guiderElement.appendTo("body");
 373      guiderElement.attr("id", myGuider.id);
 374      
 375      // Ensure myGuider.attachTo is a jQuery element.
 376      if (typeof myGuider.attachTo !== "undefined" && myGuider !== null) {
 377        guiders._attach(myGuider) && guiders._styleArrow(myGuider);
 378      }
 379      
 380      guiders._initializeOverlay();
 381      
 382      guiders._guiders[myGuider.id] = myGuider;
 383      guiders._lastCreatedGuiderID = myGuider.id;
 384      
 385      /**
 386       * If the URL of the current window is of the form
 387       * http://www.myurl.com/mypage.html#guider=id
 388       * then show this guider.
 389       */
 390      if (myGuider.isHashable) {
 391        guiders._showIfHashed(myGuider);
 392      }
 393      
 394      return guiders;
 395    }; 
 396  
 397    guiders.hideAll = function(omitHidingOverlay, next) {
 398      next = next || false;
 399  
 400      $(".guider:visible").each(function(index, elem){
 401        var myGuider = guiders._guiderById($(elem).attr('id'));
 402        if (myGuider.onHide) {
 403          myGuider.onHide(myGuider, next);
 404        }
 405      });
 406      $(".guider").fadeOut("fast");
 407      var currentGuider = guiders._guiders[guiders._currentGuiderID];
 408      if (currentGuider && currentGuider.highlight) {
 409          guiders._dehighlightElement(currentGuider.highlight);
 410      }
 411      if (typeof omitHidingOverlay !== "undefined" && omitHidingOverlay === true) {
 412        // do nothing for now
 413      } else {
 414        guiders._hideOverlay();
 415      }
 416      return guiders;
 417    };
 418  
 419    guiders.show = function(id) {
 420      if (!id && guiders._lastCreatedGuiderID) {
 421        id = guiders._lastCreatedGuiderID;
 422      }
 423    
 424      var myGuider = guiders._guiderById(id);
 425      if (myGuider.overlay) {
 426        guiders._showOverlay();
 427        // if guider is attached to an element, make sure it's visible
 428        if (myGuider.highlight) {
 429          guiders._highlightElement(myGuider.highlight);
 430        }
 431      }
 432    
 433      // You can use an onShow function to take some action before the guider is shown.
 434      if (myGuider.onShow) {
 435        myGuider.onShow(myGuider);
 436      }
 437      guiders._attach(myGuider);
 438      myGuider.elem.fadeIn("fast").data("locked", false);
 439        
 440      guiders._currentGuiderID = id;
 441      
 442      var windowHeight = guiders._windowHeight = $(window).height();
 443      var scrollHeight = $(window).scrollTop();
 444      var guiderOffset = myGuider.elem.offset();
 445      var guiderElemHeight = myGuider.elem.height();
 446      
 447      var isGuiderBelow = (scrollHeight + windowHeight < guiderOffset.top + guiderElemHeight); /* we will need to scroll down */
 448      var isGuiderAbove = (guiderOffset.top < scrollHeight); /* we will need to scroll up */
 449      
 450      if (myGuider.autoFocus && (isGuiderBelow || isGuiderAbove)) {
 451        // Sometimes the browser won't scroll if the person just clicked,
 452        // so let's do this in a setTimeout.
 453        setTimeout(guiders.scrollToCurrent, 10);
 454      }
 455      
 456      $(myGuider.elem).trigger("guiders.show");
 457  
 458      return guiders;
 459    };
 460    
 461    guiders.scrollToCurrent = function() {
 462      var currentGuider = guiders._guiders[guiders._currentGuiderID];
 463      if (typeof currentGuider === "undefined") {
 464        return;
 465      }
 466      
 467      var windowHeight = guiders._windowHeight;
 468      var scrollHeight = $(window).scrollTop();
 469      var guiderOffset = currentGuider.elem.offset();
 470      var guiderElemHeight = currentGuider.elem.height();
 471      
 472      // Scroll to the guider's position.
 473      var scrollToHeight = Math.round(Math.max(guiderOffset.top + (guiderElemHeight / 2) - (windowHeight / 2), 0));
 474      window.scrollTo(0, scrollToHeight);
 475    };
 476    
 477    // Change the bubble position after browser gets resized
 478    var _resizing = undefined;
 479    $(window).resize(function() {
 480      if (typeof(_resizing) !== "undefined") {
 481        clearTimeout(_resizing); // Prevents seizures
 482      }
 483      _resizing = setTimeout(function() {
 484        _resizing = undefined;
 485        guiders.reposition();
 486      }, 20);
 487    });
 488    
 489    return guiders;
 490  }).call(this, jQuery);


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1