Advertisement
Guest User

Untitled

a guest
Dec 6th, 2012
1,285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 65.92 KB | None | 0 0
  1. __d("PhotoSnowlift", ["array-extensions", "event-extensions", "function-extensions", "Arbiter", "AsyncDialog", "AsyncRequest", "Bootloader", "Class", "CSS", "Dialog", "DOM", "DOMControl", "FullScreen", "ImageUtils", "Keys", "LinkController", "Locale", "PageTransitions", "Parent", "PhotosConst", "PhotoSessionLog", "PhotoSnowliftAds", "PhotoStreamCache", "PhotosUtils", "PhotoViewer", "Rect", "ScrollableArea", "Style", "Toggler", "UIPagelet", "URI", "UserAgent", "Vector", "$", "computeRelativeURI", "copyProperties", "createArrayFrom", "csx", "emptyFunction", "ge", "goURI", "tx", "userAction"], function (a, b, c, d, e, f) {
  2. b('array-extensions');
  3. b('event-extensions');
  4. b('function-extensions');
  5. var g = b('Arbiter'),
  6. h = b('AsyncDialog'),
  7. i = b('AsyncRequest'),
  8. j = b('Bootloader'),
  9. k = b('Class'),
  10. l = b('CSS'),
  11. m = b('Dialog'),
  12. n = b('DOM'),
  13. o = b('DOMControl'),
  14. p = b('FullScreen'),
  15. q = b('ImageUtils'),
  16. r = b('Keys'),
  17. s = b('LinkController'),
  18. t = b('Locale'),
  19. u = b('PageTransitions'),
  20. v = b('Parent'),
  21. w = b('PhotosConst'),
  22. x = b('PhotoSessionLog'),
  23. y = b('PhotoSnowliftAds'),
  24. z = b('PhotoStreamCache'),
  25. aa = b('PhotosUtils'),
  26. ba = b('PhotoViewer'),
  27. ca = b('Rect'),
  28. da = b('ScrollableArea'),
  29. ea = b('Style'),
  30. fa = b('Toggler'),
  31. ga = b('UIPagelet'),
  32. ha = b('URI'),
  33. ia = b('UserAgent'),
  34. ja = b('Vector'),
  35. ka = b('$'),
  36. la = b('computeRelativeURI'),
  37. ma = b('copyProperties'),
  38. na = b('createArrayFrom'),
  39. oa = b('csx'),
  40. pa = b('emptyFunction'),
  41. qa = b('ge'),
  42. ra = b('goURI'),
  43. sa = b('tx'),
  44. ta = b('userAction'),
  45. ua = b('event-extensions').$E;
  46.  
  47. function va() {
  48. this.parent.construct(this);
  49. }
  50. ma(va, {
  51. STATE_ERROR: 'error',
  52. STATE_HTML: 'html',
  53. STATE_IMAGE_PIXELS: 'image_pixels',
  54. STATE_IMAGE_DATA: 'image',
  55. LOADING_TIMEOUT: 2000,
  56. PAGER_FADE: 3000,
  57. FULL_SCREEN_PADDING: 10,
  58. STAGE_HIRES_MAX: {
  59. x: 2048,
  60. y: 2048
  61. },
  62. STAGE_NORMAL_MAX: {
  63. x: 960,
  64. y: 960
  65. },
  66. STAGE_MIN: {
  67. x: 520,
  68. y: 520
  69. },
  70. SIDEBAR_SIZE_MAX: 340,
  71. SIDEBAR_SIZE_MIN: 285,
  72. STAGE_CHROME: {
  73. x: 102,
  74. y: 42
  75. },
  76. VIDEO_BOTTOM_BAR_SPACE: 40,
  77. GOPREV_AREA: 120,
  78. TIMELINE_STRETCH_WIDTH: 843,
  79. TIMELINE_STRETCH_MIN: 480,
  80. MIN_TAG_DISTANCE: 83,
  81. PADDING_MIN: 40,
  82. _instance: null,
  83. getInstance: function () {
  84. if (!va._instance) va._instance = new va();
  85. return va._instance;
  86. },
  87. initWithSpotlight: function (wa, xa) {
  88. va.getInstance().init(wa, xa);
  89. },
  90. touch: pa,
  91. addPhotoFbids: function (wa, xa, ya, za) {
  92. va.getInstance().addPhotoFbids(wa, xa, ya, za);
  93. },
  94. attachFollowFlyout: function (wa) {
  95. n.insertAfter(ka('fbPhotoSnowliftSubscribe'), wa);
  96. },
  97. attachSubscribeFlyout: function (wa) {
  98. n.insertAfter(ka('fbPhotoSnowliftSubscribe'), wa);
  99. },
  100. attachTagger: function (wa) {
  101. va.getInstance().attachTagger(wa);
  102. },
  103. preload: function (wa, xa) {
  104. va.getInstance().preload(wa, xa);
  105. },
  106. bootstrap: function (wa, xa) {
  107. if (wa && ha(wa).getQueryData().hasOwnProperty('share_id')) {
  108. j.loadModules(['SpotlightShareViewer'], function (ya) {
  109. ya.bootstrap(wa, xa);
  110. });
  111. return;
  112. }
  113. va.getInstance().bootstrap(wa, xa);
  114. },
  115. closeRefresh: function () {
  116. va.getInstance().closeRefresh();
  117. },
  118. deletePhoto: function (wa) {
  119. va.getInstance().deletePhoto(wa);
  120. },
  121. getImage: function () {
  122. return va.getInstance().getImage();
  123. },
  124. getImageId: function () {
  125. return va.getInstance().getImageId();
  126. },
  127. getLoadQuery: function () {
  128. return va.getInstance().getLoadQuery();
  129. },
  130. getRHCBody: function () {
  131. return va.getInstance().getRHCBody();
  132. },
  133. getRHCFooter: function () {
  134. return va.getInstance().getRHCFooter();
  135. },
  136. getRHCHeader: function () {
  137. return va.getInstance().getRHCHeader();
  138. },
  139. getRoot: function () {
  140. return va.getInstance().getRoot();
  141. },
  142. likePhotoSkipConfirmation: function (wa) {
  143. va.getInstance().likePhotoSkipConfirmation(wa);
  144. },
  145. saveTagsFromPayload: function (wa) {
  146. va.getInstance().saveTagsFromPayload(wa);
  147. },
  148. saveTagsFromPayloadDelayed: function (wa) {
  149. va.saveTagsFromPayload.curry(wa).defer(2000);
  150. },
  151. handleServerError: function (wa, xa) {
  152. va.getInstance().handleServerError(wa, xa);
  153. },
  154. storeFromData: function (wa) {
  155. va.getInstance().storeFromData(wa);
  156. },
  157. swapData: function () {
  158. va.getInstance().swapData();
  159. },
  160. touchMarkup: pa,
  161. updateTotalCount: function (wa, xa, ya) {
  162. va.getInstance().updateTotalCount(wa, xa, ya);
  163. }
  164. });
  165. k.extend(va, ba);
  166. ma(va.prototype, {
  167. switchTimer: null,
  168. imageRefreshTimer: null,
  169. imageLoadingTimer: null,
  170. lastPage: 0,
  171. currentMinSize: null,
  172. currentImageSize: null,
  173. resetUriStack: true,
  174. thumbSrc: null,
  175. shouldStretch: false,
  176. stageMax: va.STAGE_NORMAL_MAX,
  177. stageChrome: va.STAGE_CHROME,
  178. stagePagerPrev: null,
  179. ua: null,
  180. PhotoTagger: null,
  181. showHover: false,
  182. skipLikePhotoConfirmation: false,
  183. isShowingLikePhotoConfirmation: false,
  184. preload: function (wa, xa) {
  185. j.loadModules(['PhotoTagger', 'fb-photos-snowlift-css', 'Live', 'PhotoTagApproval', 'PhotoTags', 'TagTokenizer', 'fb-photos-snowlift-fullscreen-css'], function (za) {
  186. this.PhotoTagger = za;
  187. }.bind(this));
  188. var ya = this.getImageSrc(ha(wa).getQueryData());
  189. if (ya)(new Image()).src = ya;
  190. },
  191. bootstrap: function (wa, xa) {
  192. if (wa && ha(wa).getQueryData().makeprofile) {
  193. this.enableCropperOnInit = true;
  194. this.isUserProfilePic = ha(wa).getQueryData().makeuserprofile;
  195. this.isInProfilePicAlbum = ha(wa).getQueryData().inprofilepicalbum;
  196. }
  197. this.preload(wa, xa);
  198. if (this.closeDirty) {
  199. this.bootstrap.bind(this, wa, xa).defer();
  200. return;
  201. }
  202. y.reset();
  203. this.resetUriStack = true;
  204. if (this.isOpen) if (this.openExplicitly) {
  205. this.closeCleanup();
  206. this.resetUriStack = false;
  207. } else return;
  208. this.ua = ta('snowlift', xa).uai('open');
  209. this.returningToStart = false;
  210. this.loading && l.removeClass(this.loading, 'loading');
  211. if (xa) {
  212. l.addClass((this.loading = xa), 'loading');
  213. this.getThumbAndSize(xa);
  214. } else this.loading = null;
  215. g.inform('PhotoSnowlift.GO', wa, g.BEHAVIOR_STATE);
  216. this.loadFrameIfUninitialized();
  217. },
  218. getCurrentImageServerSizeDimensions: function () {
  219. return this.stream.getCurrentImageData().dimensions;
  220. },
  221. getEventPrefix: function () {
  222. return 'PhotoSnowlift';
  223. },
  224. getRoot: function () {
  225. return this.root;
  226. },
  227. getSourceString: function () {
  228. return 'snowlift';
  229. },
  230. getVersionConst: function () {
  231. return w.VIEWER_SNOWLIFT;
  232. },
  233. getImage: function () {
  234. return this.image;
  235. },
  236. getImageId: function () {
  237. return this.stream.getCursor();
  238. },
  239. getRHCHeader: function () {
  240. return this.rhcHeader;
  241. },
  242. getRHCBody: function () {
  243. return this.ufiForm;
  244. },
  245. getRHCFooter: function () {
  246. return this.rhcFooter;
  247. },
  248. getLoadQuery: function () {
  249. return this.loadQuery;
  250. },
  251. getCurrentPhotoInfo: function () {
  252. var wa = this.stream.getCurrentImageData();
  253. if (wa) return wa.info;
  254. return null;
  255. },
  256. getOwnerId: function () {
  257. var wa = this.stream.getCurrentImageData();
  258. if (wa) return wa.info.owner;
  259. return null;
  260. },
  261. getThumbAndSize: function (wa) {
  262. this.currentImageSize = null;
  263. this.thumbSrc = null;
  264. var xa = ha(wa.getAttribute('ajaxify')).getQueryData();
  265. if (!xa.size) return;
  266. var ya = ja.deserialize(xa.size);
  267. if (!ya.x || !ya.y) return;
  268. this.currentImageSize = ya;
  269. if (!l.hasClass(wa, 'uiMediaThumb') && !l.hasClass(wa, 'uiPhotoThumb') && !l.hasClass(wa, 'uiScaledThumb')) return;
  270. if (wa.getAttribute('data-cropped')) return;
  271. var za = n.scry(wa, 'img')[0],
  272. ab = n.scry(wa, 'i')[0],
  273. bb = v.byAttribute(wa, 'data-size');
  274. this.shouldStretch = bb && this.currentImageSize && za && bb.getAttribute('data-size') === "2" && this.currentImageSize.x > this.currentImageSize.y && this.currentImageSize.x <= va.TIMELINE_STRETCH_WIDTH && za.offsetWidth === va.TIMELINE_STRETCH_WIDTH;
  275. var cb;
  276. if (za) {
  277. cb = za.src;
  278. } else if (ab) {
  279. cb = ea.get(ab, 'backgroundImage').replace(/.*url\("?([^"]*)"?\).*/, '$1');
  280. } else return;
  281. this.thumbSrc = cb;
  282. },
  283. loadFrameIfUninitialized: function () {
  284. if (this.root) return;
  285. new i('/ajax/photos/snowlift/init.php').setAllowCrossPageTransition(true).setMethod('GET').setReadOnly(true).send();
  286. },
  287. init: function (wa, xa) {
  288. this.init = pa;
  289. this.showHover = xa.pivot_hover;
  290. x.setEndMetrics(xa.pivot_end_metric);
  291. this.showEndPivot = xa.pivot_end;
  292. this.enableSnowliftProfilePicCropper = xa.snowlift_profile_pic_cropper;
  293. this.fullscreen = p.isSupported();
  294. this.showOGVideos = xa.og_videos;
  295. this.stageMax = va.STAGE_HIRES_MAX;
  296. this.spotlight = wa;
  297. this.spotlight.subscribe('blur', function () {
  298. this.closingAction = x.OUTSIDE;
  299. }.bind(this));
  300. this.spotlight.subscribe('hide', this.closeHandler.shield(this));
  301. this.spotlight.subscribe('key', this.keyHandler.bind(this));
  302. this.initializeNodes(this.spotlight.getRoot());
  303. y.init(this.sideAdUnit, this, xa);
  304. if (!this.subscription) {
  305. s.registerHandler(this.handleNavigateAway.bind(this));
  306. this.subscription = g.subscribe('PhotoSnowlift.GO', function (ya, za) {
  307. this.openExplicitly = true;
  308. this.loading && l.removeClass(this.loading, 'loading');
  309. this.open(za);
  310. }.bind(this));
  311. }
  312. this.transitionHandlerRegistered = false;
  313. this.returningToStart = false;
  314. u.registerHandler(this.openHandler.bind(this));
  315. this.openHandlerRegistered = true;
  316. g.subscribe('PhotoTagApproval.HILITE_TAG', this.onHiliteTag.bind(this));
  317. g.subscribe('PhotoTagApproval.UPDATE_TAG_BOX', this.onUpdateTagBox.bind(this));
  318. if (this.fullscreen) p.subscribe('changed', this.onFullScreenChange.bind(this));
  319. },
  320. onFullScreenChange: function () {
  321. var wa = p.isFullScreen();
  322. l.conditionClass(document.body, 'fbPhotoSnowliftFullScreenMode', wa);
  323. if (wa) {
  324. if (!l.hasClass(this.root, 'fbPhotoSnowliftEditMode')) this.collapseRHC();
  325. var xa = this.stream.getCurrentImageData();
  326. if (xa && xa.url && this.image.src !== xa.url && this.shouldShowHiRes(xa)) this.switchImage(xa.url);
  327. this.adjustForResize();
  328. } else {
  329. this.uncollapseRHC();
  330. if (ia.chrome() && !l.hasClass(this.root, 'fbPhotoSnowliftEditMode')) this.page(0, false);
  331. g.inform('reflow');
  332. }
  333. fa.hide();
  334. if (this.cropper) this.cropper.resetPhoto();
  335. },
  336. initializeNodes: function (wa) {
  337. this.root = wa;
  338. this.container = n.find(wa, 'div.fbPhotoSnowliftContainer');
  339. this.snowliftPopup = n.find(this.container, 'div.fbPhotoSnowliftPopup');
  340. this.rhc = n.find(this.snowliftPopup, 'div.rhc');
  341. this.rhcHeader = n.find(this.rhc, 'div.rhcHeader');
  342. this.rhcFooter = n.find(this.rhc, 'div.rhcFooter');
  343. this.ufiForm = n.find(this.rhc, 'form.fbPhotosSnowliftFeedbackForm');
  344. this.ufiInputContainer = n.find(this.rhc, 'div.fbPhotosSnowboxFeedbackInput');
  345. this.scroller = n.find(this.ufiForm, 'div.rhcScroller');
  346. this.scrollerBody = n.find(this.scroller, 'div.uiScrollableAreaBody');
  347. this.stageWrapper = n.find(this.snowliftPopup, 'div.stageWrapper');
  348. this.overlay = n.find(this.snowliftPopup, 'div.snowliftOverlay');
  349. this.errorBox = n.find(this.stageWrapper, 'div.stageError');
  350. this.image = n.find(this.stageWrapper, 'img.spotlight');
  351. this.stage = n.find(this.stageWrapper, 'div.stage');
  352. this.videoStage = n.find(this.stageWrapper, 'div.videoStage');
  353. this.prevPager = n.find(this.snowliftPopup, 'a.snowliftPager.prev');
  354. this.nextPager = n.find(this.snowliftPopup, 'a.snowliftPager.next');
  355. this.stageActions = n.find(wa, 'div.stageActions');
  356. this.buttonActions = n.find(this.stageActions, 'div.fbPhotosPhotoButtons');
  357. this.sideAdUnit = n.find(wa, "._24q");
  358. g.inform('Amoeba/instrumentMulti', [
  359. [this.container, 'snowlift'],
  360. [this.rhc, 'rhc'],
  361. [this.rhcHeader, 'rhc_header'],
  362. [this.ufiForm, 'ufi_form'],
  363. [this.ufiInputContainer, 'ufi_input'],
  364. [this.prevPager, 'prev_pager'],
  365. [this.nextPager, 'next_pager'],
  366. [this.stageActions, 'stage_actions'],
  367. [this.sideAdUnit, 'side_ads']
  368. ], g.BEHAVIOR_PERSISTENT);
  369. l.conditionClass(this.root, 'fullScreenAvailable', this.fullscreen);
  370. },
  371. initializeScroller: function () {
  372. this.initializeScroller = pa;
  373. this.scrollableArea = da.fromNative(this.scroller, {
  374. fade: true,
  375. persistent: true
  376. });
  377. var wa = function (event) {
  378. var xa = ua(event).getTarget();
  379. if (n.contains(this.ufiInputContainer, xa)) {
  380. var ya = o.getInstance(xa);
  381. if (ya) {
  382. this.scrollableArea.scrollToBottom();
  383. var za = ya.subscribe('resize', function () {
  384. var bb = this.scrollableArea.isScrolledToBottom();
  385. this.adjustScroller();
  386. bb && this.scrollableArea.scrollToBottom();
  387. }.bind(this)),
  388. ab = Event.listen(xa, 'blur', function () {
  389. ya.unsubscribe(za);
  390. ab.remove();
  391. });
  392. }
  393. }
  394. }.bind(this);
  395. g.subscribe('ufi/changed', function (xa, ya) {
  396. if (this.ufiForm === ya.form) {
  397. this.adjustScrollerIfNecessary();
  398. this.scrollableArea.scrollToBottom();
  399. }
  400. }.bind(this));
  401. Event.listen(this.rhc, 'click', function (event) {
  402. var xa = event.getTarget();
  403. if (v.byTag(xa, 'a') || v.byTag(xa, 'button') || n.isNodeOfType(xa, 'input')) this.adjustScrollerIfNecessary();
  404. }.bind(this));
  405. g.subscribe(['reflow', 'CommentUFI.Pager'], function () {
  406. if (this.isOpen) this.adjustScroller();
  407. }.bind(this));
  408. if (this.ufiForm.attachEvent) {
  409. this.ufiForm.attachEvent('onfocusin', wa);
  410. } else this.ufiForm.addEventListener('focus', wa, true);
  411. },
  412. openHandler: function (wa) {
  413. if (this.isOpen || wa.getPath() != '/photo.php' || this.returningToStart || wa.getQueryData().closeTheater || wa.getQueryData().permPage || wa.getQueryData().makeprofile) {
  414. this.openHandlerRegistered = false;
  415. return false;
  416. }
  417. this.open(wa);
  418. this._uriStack.push(ha(wa).getQualifiedURI().toString());
  419. u.transitionComplete(true);
  420. return true;
  421. },
  422. getImageSrc: function (wa) {
  423. if (wa.smallsrc) {
  424. if (!wa.size) return wa.smallsrc;
  425. var xa = ja.deserialize(wa.size),
  426. ya = this.getStageSize(xa);
  427. if (ya.x <= va.STAGE_NORMAL_MAX.x && ya.y <= va.STAGE_NORMAL_MAX.y) return wa.smallsrc;
  428. }
  429. return wa.src;
  430. },
  431. open: function (wa) {
  432. var xa = ha(wa).getQueryData(),
  433. ya = this.getImageSrc(xa);
  434. if (ya) {
  435. delete xa.src;
  436. delete xa.smallsrc;
  437. }
  438. if (this.resetUriStack) this._uriStack = [];
  439. if (!this.initialLoad) {
  440. xa.firstLoad = true;
  441. this.initialLoad = true;
  442. }
  443. this.sessionID = Date.now();
  444. this.loadQuery = ma(xa, {
  445. ssid: this.sessionID
  446. });
  447. this.isOpen = true;
  448. this.pagersShown = false;
  449. this.refreshOnClose = false;
  450. this.hilitedTag = null;
  451. this.loadingStates = {
  452. image: false,
  453. html: false
  454. };
  455. this.replaceUrl = false;
  456. this.stream = new z();
  457. this.stream.init(w.VIEWER_SNOWLIFT, 'PhotoViewerPagelet');
  458. this.fetchInitialData();
  459. this.setLoadingState(va.STATE_HTML, true);
  460. this.rhcCollapsed = false;
  461. j.loadModules(['fb-photos-snowlift-css'], this._open.bind(this, wa, ya));
  462. if (this.showEndPivot) j.loadModules(['PhotoPivot'], function (za) {
  463. this.pivots = za.getInstance();
  464. if (xa.relevant_count) this.pivots.setRelevantCount(xa.relevant_count);
  465. }.bind(this));
  466. if (this.enableSnowliftProfilePicCropper) j.loadModules(['SnowliftPicCropper'], function (za) {
  467. this.cropper = za.getInstance(this);
  468. this.cropper.init();
  469. if (this.enableCropperOnInit) {
  470. var ab = g.subscribe('PhotoSnowlift.SWITCH_IMAGE', function () {
  471. if (this.isInProfilePicAlbum) {
  472. this.cropper.showPicInProfileAlbumDialog();
  473. } else this.cropper.enableCropping(this.isUserProfilePic);
  474. g.unsubscribe(ab);
  475. }.bind(this));
  476. this.enableCropperOnInit = false;
  477. }
  478. }.bind(this));
  479. j.loadModules(['PhotosButtonTooltips'], function (za) {
  480. za.init();
  481. });
  482. },
  483. _open: function (wa, xa) {
  484. this.createLoader(xa);
  485. this.spotlight.show();
  486. this.ua && this.ua.add_event('frame');
  487. g.inform('layer_shown', {
  488. type: 'PhotoSnowlift'
  489. });
  490. g.inform('PhotoSnowlift.OPEN');
  491. this.stageHandlers = [Event.listen(window, 'resize', this.adjustForResize.bind(this)), Event.listen(this.stageWrapper, 'click', this.buttonListener.bind(this)), Event.listen(this.stageWrapper, 'mouseleave', function (event) {
  492. this.unhiliteAllTags();
  493. this.hidePagers();
  494. }.bind(this)), Event.listen(this.stageWrapper, 'mousemove', this.hilitePagerOnMouseMove.bind(this)), Event.listen(this.stageWrapper, 'mousemove', this.hiliteTagsOnMouseMove.bind(this)), Event.listen(this.overlay, 'mouseenter', this.unhiliteAllTags.bind(this))];
  495. this.stageHandlers.push(Event.listen(this.container, 'click', (function (event) {
  496. var ab = event.getTarget();
  497. if (v.byClass(ab, 'rotateRight')) {
  498. this.rotate('right');
  499. } else if (v.byClass(ab, 'rotateLeft')) {
  500. this.rotate('left');
  501. } else if (v.byClass(ab, 'closeTheater')) {
  502. if (p.isFullScreen()) {
  503. p.toggleFullScreen();
  504. return;
  505. }
  506. this.closingAction = x.X;
  507. this.closeHandler();
  508. } else if (this.fullscreen) if (v.byClass(ab, 'fbPhotoSnowliftFullScreen')) {
  509. this.toggleFullScreen();
  510. } else if (v.byClass(ab, 'fbPhotoSnowliftCollapse')) this.toggleCollapse();
  511. }).bind(this)));
  512. var ya = qa('fbPhotoSnowliftFeedback');
  513. if (ya) this.stageHandlers.push(Event.listen(ya, 'click', function (event) {
  514. if (v.byClass(event.getTarget(), 'like_link') || v.byClass(event.getTarget(), 'UFILikeLink')) this.toggleLikeButton();
  515. var ab = v.byClass(event.getTarget(), 'uiUfiCollapsedComment');
  516. if (ab) l.addClass(ab, 'uiUfiCollapsedCommentToggle');
  517. }.bind(this)));
  518. var za = qa('fbPhotoSnowliftOnProfile');
  519. if (za) this.stageHandlers.push(Event.listen(za, 'click', function (event) {
  520. if (v.byClass(event.getTarget(), 'fbPhotoRemoveFromProfileLink')) this.refreshOnClose = true;
  521. }.bind(this)));
  522. if (this.resetUriStack) this.startingURI = ha.getMostRecentURI().addQueryData({
  523. closeTheater: 1
  524. }).getUnqualifiedURI();
  525. if (!xa) this.setLoadingState(va.STATE_IMAGE_DATA, true);
  526. if (!this.transitionHandlerRegistered) {
  527. u.registerHandler(this.transitionHandler.bind(this));
  528. this.transitionHandlerRegistered = true;
  529. }
  530. x.initLogging(x.SNOWLIFT);
  531. if (this.pivots) x.setRelevantCount(this.pivots.relevantCount);
  532. },
  533. toggleFullScreen: function () {
  534. var wa = p.toggleFullScreen(document.documentElement);
  535. if (wa) {
  536. var xa = this.stream.getCurrentImageData();
  537. if (xa && xa.url && this.image.src !== xa.url && this.shouldShowHiRes(xa))(new Image()).src = xa.url;
  538. x.logEnterFullScreen(this.stream.getCursor());
  539. }
  540. },
  541. getStream: function () {
  542. return this.stream;
  543. },
  544. fetchInitialData: function () {
  545. this.ua && this.ua.add_event('init_data');
  546. this.stream.waitForInitData();
  547. ga.loadFromEndpoint('PhotoViewerInitPagelet', null, this.loadQuery, {
  548. usePipe: true,
  549. jsNonblock: true,
  550. crossPage: true
  551. });
  552. },
  553. toggleCollapse: function () {
  554. if (this.rhcCollapsed) {
  555. this.uncollapseRHC();
  556. } else this.collapseRHC();
  557. },
  558. collapseRHC: function () {
  559. this.rhcCollapsed = true;
  560. l.addClass(this.root, 'collapseRHC');
  561. this.adjustForResize();
  562. },
  563. uncollapseRHC: function () {
  564. this.rhcCollapsed = false;
  565. l.removeClass(this.root, 'collapseRHC');
  566. this.adjustForResize();
  567. },
  568. closeHandler: function () {
  569. if (!this.isOpen) return;
  570. this.closingAction = this.closingAction || x.ESC;
  571. if (ha.getMostRecentURI().addQueryData({
  572. closeTheater: 1
  573. }).getUnqualifiedURI().toString() == this.startingURI.toString()) {
  574. this.close();
  575. return;
  576. }
  577. this.returnToStartingURI(this.refreshOnClose);
  578. this.close();
  579. },
  580. returnToStartingURI: function (wa, xa) {
  581. if (!wa) if (xa) {
  582. this.squashNextTransition(ra.curry(xa));
  583. } else this.squashNextTransition();
  584. this.returningToStart = true;
  585. var ya = g.subscribe('page_transition', function () {
  586. this.returningToStart = false;
  587. ya.unsubscribe();
  588. }),
  589. za = wa || isNaN(ia.opera()),
  590. ab = this._uriStack.length;
  591. if (za && ab < window.history.length) {
  592. window.history.go(-ab);
  593. } else {
  594. var bb = this.startingURI,
  595. cb = new ha(bb).removeQueryData('closeTheater');
  596. if (bb.getQueryData().sk == 'approve' && bb.getPath() == '/profile.php') {
  597. cb.removeQueryData('highlight');
  598. cb.removeQueryData('notif_t');
  599. }
  600. ra(cb);
  601. }
  602. },
  603. squashNextTransition: function (wa) {
  604. this.squashNext = true;
  605. u.registerHandler(function xa() {
  606. if (this.squashNext) {
  607. this.squashNext = false;
  608. if (wa) wa.defer();
  609. u.transitionComplete(true);
  610. return true;
  611. }
  612. return false;
  613. }.bind(this), 7);
  614. },
  615. handleNavigateAway: function (wa) {
  616. var xa = la(u._most_recent_uri.getQualifiedURI(), wa.getAttribute('href'));
  617. if (this.isOpen && (xa instanceof ha) && xa.getUnqualifiedURI().toString() != this.startingURI.toString() && xa.getPath() != '/photo.php') {
  618. if (!this.closingAction) this.closingAction = x.NAVIGATE;
  619. this.returnToStartingURI(false, xa);
  620. this.close();
  621. return false;
  622. }
  623. return true;
  624. },
  625. close: function () {
  626. if (!this.isOpen) return;
  627. this.isOpen = false;
  628. if (this.fullscreen) p.disableFullScreen();
  629. ta('snowlift').uai('close');
  630. this.cropper && this.cropper.disableCropping();
  631. this.spotlight.hide();
  632. this.openExplicitly = false;
  633. this.closeDirty = true;
  634. this.closeCleanup.bind(this).defer();
  635. },
  636. closeCleanup: function () {
  637. this.closeDirty = false;
  638. l.removeClass(this.root, 'dataLoading');
  639. x.logPhotoViews(this.closingAction);
  640. this.destroy();
  641. l.hide(this.errorBox);
  642. l.hide(this.image);
  643. this.currentImageSize = null;
  644. this.thumbSrc = null;
  645. this.shouldStretch = false;
  646. this.resetUriStack = true;
  647. l.removeClass(this.stageWrapper, 'showVideo');
  648. n.empty(this.videoStage);
  649. this.uncollapseRHC();
  650. this.currentMinSize = null;
  651. this.setStagePagersState('reset');
  652. this.recacheData();
  653. n.empty(this.sideAdUnit);
  654. this.stream.destroy();
  655. var wa = this.closingAction === x.NAVIGATE;
  656. this.closingAction = null;
  657. if (!this.openHandlerRegistered) {
  658. u.registerHandler(this.openHandler.bind(this));
  659. this.openHandlerRegistered = true;
  660. }
  661. g.inform('layer_hidden', {
  662. type: 'PhotoSnowlift'
  663. });
  664. g.inform('PhotoSnowlift.CLOSE', wa);
  665. this.root.setAttribute('aria-busy', 'true');
  666. },
  667. createLoader: function (wa) {
  668. if (this.currentImageSize === null) {
  669. this.adjustStageSize(va.STAGE_MIN);
  670. } else {
  671. var xa = this.getStageSize(this.currentImageSize);
  672. xa = new ja(Math.max(xa.x, va.STAGE_MIN.x), Math.max(xa.y, va.STAGE_MIN.y));
  673. var ya = this.getImageSizeInStage(this.currentImageSize, xa);
  674. if (this.thumbSrc === null) {
  675. this.adjustStageSize(ya);
  676. } else this.useImage(n.create('img', {
  677. className: 'spotlight',
  678. alt: '',
  679. src: this.thumbSrc,
  680. style: {
  681. width: ya.x + 'px',
  682. height: ya.y + 'px'
  683. }
  684. }), ya, false);
  685. }
  686. this.setLoadingState(this.STATE_IMAGE_PIXELS, true);
  687. if (wa)(function () {
  688. var za = new Image();
  689. za.onload = a.async_callback(function () {
  690. if (!this.isOpen || this.pendingImageUrl != wa) return;
  691. if (!this.stream || !this.stream.errorInCurrent()) {
  692. this.switchImage(wa, this.currentImageSize);
  693. this.ua && this.ua.add_event('image');
  694. this.setLoadingState(va.STATE_IMAGE_DATA, false);
  695. }
  696. }.bind(this), 'photo_theater');
  697. za.src = this.pendingImageUrl = wa;
  698. }).bind(this).defer();
  699. l.hide(this.stageActions);
  700. this.setStagePagersState('disabled');
  701. },
  702. initDataFetched: function (wa) {
  703. x.setPhotoSet(this.stream.getPhotoSet());
  704. x.setLogFbids(wa.logids);
  705. var xa = this.stream.getCurrentImageData();
  706. x.addPhotoView(xa.info, this.shouldShowHiRes(xa), this.fullscreen && p.isFullScreen());
  707. if (!this.pageHandlers) this.pageHandlers = [Event.listen(this.root, 'click', this.pageListener.bind(this)), Event.listen(this.root, 'mouseleave', this.mouseLeaveListener.bind(this))];
  708. l.show(this.stageActions);
  709. this.root.setAttribute('aria-busy', 'false');
  710. this.isLoggedInViewer = wa.loggedin;
  711. this.disableAdsForSession = wa.disablesessionads || !this.isLoggedInViewer;
  712. this.disableAds = this.disableAdsForSession || wa.fromad;
  713. this.loadAds();
  714. },
  715. adjustScrollerIfNecessary: function () {
  716. clearTimeout(this.scrollerTimeout);
  717. this.scrollerTimeout = this.adjustScroller.bind(this).defer();
  718. },
  719. adjustScroller: function () {
  720. clearTimeout(this.scrollerTimeout);
  721. this.initializeScroller();
  722. this.scrollableArea.resize();
  723. var wa = ja.getElementDimensions(this.rhc),
  724. xa = wa.y;
  725. xa -= ja.getElementDimensions(this.rhcHeader).y;
  726. xa -= ja.getElementDimensions(this.ufiInputContainer).y;
  727. var ya = ja.getElementDimensions(this.scrollerBody).y;
  728. if (ya >= xa) {
  729. ea.set(this.scroller, 'height', xa + 'px');
  730. l.addClass(this.rhc, 'pinnedUfi');
  731. xa = 0;
  732. } else {
  733. ea.set(this.scroller, 'height', 'auto');
  734. l.removeClass(this.rhc, 'pinnedUfi');
  735. xa -= ya;
  736. }
  737. var za = ja.getElementDimensions(this.ufiInputContainer).y;
  738. ea.set(this.ufiForm, 'padding-bottom', za + 'px');
  739. y.resize(new ja(wa.x, xa));
  740. this.scrollableArea.adjustGripper();
  741. },
  742. adjustForResize: function () {
  743. this.currentMinSize = null;
  744. this.adjustStageSize();
  745. this.adjustForNewData();
  746. },
  747. shouldShowHiRes: function (wa) {
  748. if (!wa || !wa.smallurl) return false;
  749. var xa = this.getStageSize(wa.dimensions),
  750. ya = this.getImageSizeInStage(wa.dimensions, xa);
  751. return (ya.x > va.STAGE_NORMAL_MAX.x || ya.y > va.STAGE_NORMAL_MAX.y);
  752. },
  753. getImageURL: function (wa) {
  754. if (wa.video) {
  755. return null;
  756. } else if (wa.smallurl && !this.shouldShowHiRes(wa)) return wa.smallurl;
  757. return wa.url;
  758. },
  759. getImageDimensions: function (wa) {
  760. if (wa.smalldims && (!this.shouldShowHiRes(wa) || this.image.src === wa.smallurl)) return wa.smalldims;
  761. return wa.dimensions;
  762. },
  763. getStageSize: function (wa, xa) {
  764. var ya = ja.getViewportDimensions(),
  765. za = new ja(wa.x, wa.y);
  766. if (xa) za = new ja(Math.max(wa.x, xa.x), Math.max(wa.y, xa.y));
  767. var ab, bb;
  768. if (this.fullscreen && p.isFullScreen()) {
  769. return new ja((this.rhcCollapsed ? screen.width : screen.width - va.SIDEBAR_SIZE_MAX), screen.height - va.FULL_SCREEN_PADDING * 2);
  770. } else {
  771. ab = Math.min(za.x, this.stageMax.x, (ya.x - va.SIDEBAR_SIZE_MAX - va.STAGE_CHROME.x));
  772. bb = Math.min(za.y, this.stageMax.y, ya.y - va.STAGE_CHROME.y);
  773. }
  774. if (ab === 0 && bb === 0) return new ja(0, 0);
  775. var cb = ab / bb,
  776. db = za.x / za.y;
  777. if (cb < db) return new ja(ab, Math.round(ab / db));
  778. return new ja(Math.round(bb * db), bb);
  779. },
  780. getImageSizeInStage: function (wa, xa) {
  781. var ya = wa.x,
  782. za = wa.y;
  783. if (ya >= xa.x || za >= xa.y) {
  784. var ab = xa.x / xa.y,
  785. bb = ya / za;
  786. if (ab < bb) {
  787. ya = xa.x;
  788. za = Math.round(ya / bb);
  789. } else if (ab > bb) {
  790. za = xa.y;
  791. ya = Math.round(za * bb);
  792. } else {
  793. ya = xa.x;
  794. za = xa.y;
  795. }
  796. }
  797. return new ja(ya, za);
  798. },
  799. adjustStageSize: function (wa) {
  800. var xa = this.currentImageSize;
  801. if (wa) {
  802. xa = wa;
  803. } else {
  804. var ya = this.stream && this.stream.getCurrentImageData();
  805. if (ya) xa = this.getImageDimensions(ya);
  806. }
  807. if (!xa) return;
  808. this.currentImageSize = xa;
  809. var za = 0;
  810. if (this.shouldStretch && !this.getVideoOnStage() && xa.x > xa.y && xa.x <= va.TIMELINE_STRETCH_WIDTH && xa.x >= va.TIMELINE_STRETCH_MIN) {
  811. xa.y = Math.round(xa.y * va.TIMELINE_STRETCH_WIDTH / xa.x);
  812. xa.x = va.TIMELINE_STRETCH_WIDTH;
  813. } else if (this.getVideoOnStage()) {
  814. za = va.VIDEO_BOTTOM_BAR_SPACE * 2;
  815. xa.y += za;
  816. }
  817. var ab = this.getStageSize(xa, this.currentMinSize);
  818. if (!this.currentMinSize) this.currentMinSize = new ja(0, 0);
  819. this.currentMinSize = new ja(Math.max(ab.x, va.STAGE_MIN.x, this.currentMinSize.x), Math.max(ab.y, va.STAGE_MIN.y, this.currentMinSize.y));
  820. var bb = this.getImageSizeInStage(xa, this.currentMinSize),
  821. cb = this.currentMinSize.x - bb.x,
  822. db = this.currentMinSize.y - bb.y;
  823. if (cb > 0 && cb < va.PADDING_MIN) {
  824. this.currentMinSize.x -= cb;
  825. } else if (db > 0 && db < va.PADDING_MIN) this.currentMinSize.y -= db;
  826. var eb = this.currentMinSize.x + va.SIDEBAR_SIZE_MAX;
  827. if (this.rhcCollapsed) eb = this.currentMinSize.x;
  828. this.snowliftPopup.style.cssText = 'width:' + eb + 'px;' + 'height:' + this.currentMinSize.y + 'px;';
  829. var fb = this.currentMinSize.y - za + 'px';
  830. if (ia.firefox() || ia.ie() < 8) {
  831. var gb = ea.get(this.stageWrapper, 'font-size');
  832. if (ia.ie() && gb.indexOf('px') < 0) {
  833. var hb = n.create('div');
  834. hb.style.fontSize = gb;
  835. hb.style.height = '1em';
  836. gb = hb.style.pixelHeight;
  837. }
  838. fb = ((this.currentMinSize.y - za) / parseFloat(gb)) + 'em';
  839. }
  840. this.stageWrapper.style.cssText = 'width:' + this.currentMinSize.x + 'px;' + 'line-height:' + fb + ';';
  841. if (ia.ie() < 8) {
  842. ea.set(this.root, 'height', ja.getViewportDimensions().y + 'px');
  843. ea.set(this.container, 'min-height', (this.currentMinSize.y + va.STAGE_CHROME.y) + 'px');
  844. }
  845. this.image.style.cssText = 'width:' + bb.x + 'px;' + 'height:' + bb.y + 'px;';
  846. this.adjustScrollerIfNecessary();
  847. },
  848. adjustForNewData: function () {
  849. if (!this.image) return;
  850. var wa = n.scry(this.stage, 'div.tagsWrapper')[0],
  851. xa = ja.getElementDimensions(this.image);
  852. if (wa) {
  853. ea.set(wa, 'width', xa.x + 'px');
  854. ea.set(wa, 'height', xa.y + 'px');
  855. if (ia.ie() <= 7) {
  856. var ya = n.scry(this.root, 'div.tagContainer')[0];
  857. if (ya) l.conditionClass(wa, 'ie7VerticalFix', ja.getElementDimensions(ya).y > xa.y);
  858. }
  859. }
  860. },
  861. setLoadingState: function (wa, xa) {
  862. switch (wa) {
  863. case va.STATE_IMAGE_PIXELS:
  864. l.conditionClass(this.root, 'imagePixelsLoading', xa);
  865. break;
  866. case va.STATE_IMAGE_DATA:
  867. this.loadingStates[wa] = xa;
  868. l.conditionClass(this.root, 'imageLoading', xa);
  869. break;
  870. case va.STATE_HTML:
  871. this.loadingStates[wa] = xa;
  872. l.conditionClass(this.root, 'dataLoading', xa);
  873. this.rhc.setAttribute('aria-busy', xa ? 'true' : 'false');
  874. break;
  875. }
  876. },
  877. destroy: function () {
  878. this.stageHandlers.forEach(function (wa) {
  879. wa.remove();
  880. });
  881. if (this.pageHandlers) {
  882. this.pageHandlers.forEach(function (wa) {
  883. wa.remove();
  884. });
  885. this.pageHandlers = null;
  886. }
  887. },
  888. checkState: function (wa) {
  889. if (wa != va.STATE_ERROR && !this.loadingStates[wa]) return;
  890. switch (wa) {
  891. case va.STATE_IMAGE_DATA:
  892. var xa = this.stream.getCurrentImageData();
  893. if (xa) {
  894. var ya = this.getImageURL(xa);
  895. if (ya) {
  896. this.switchImage(ya, null, true);
  897. } else if (xa.video) this.switchVideo(xa.video, true);
  898. this.setLoadingState(wa, false);
  899. }
  900. break;
  901. case va.STATE_HTML:
  902. if (this.stream.getCurrentHtml()) {
  903. this.swapData();
  904. this.setLoadingState(wa, false);
  905. }
  906. break;
  907. default:
  908. if (this.stream.errorInCurrent()) {
  909. l.hide(this.image);
  910. l.show(this.errorBox);
  911. }
  912. break;
  913. }
  914. },
  915. buttonListener: function (event) {
  916. var wa = event.getTarget(),
  917. xa = Date.now();
  918. if (v.byClass(wa, 'fbPhotoTagApprovalBox')) return;
  919. if (xa - this.lastPage < 350) return;
  920. if (v.byClass(wa, 'fbPhotosPhotoLike')) {
  921. this.likePhoto();
  922. } else if (v.byClass(wa, 'tagApproveIgnore')) this.updateTagBox(event, wa);
  923. },
  924. likePhoto: function () {
  925. x.addButtonLike();
  926. var wa = ka('fbPhotoSnowliftFeedback'),
  927. xa = n.scry(wa, 'button.like_link')[0];
  928. if (!xa) xa = n.scry(wa, 'a.UFILikeLink')[0];
  929. var ya = xa.getAttribute('href');
  930. if (p.isFullScreen()) if (ia.chrome()) xa.setAttribute('href', 'javascript:;');
  931. xa.click();
  932. xa.setAttribute('href', ya);
  933. },
  934. toggleLikeButton: function () {
  935. var wa = n.scry(this.buttonActions, 'a.fbPhotosPhotoLike')[0];
  936. if (wa) {
  937. l.toggleClass(wa, 'viewerLikesThis');
  938. l.removeClass(wa, 'viewerAlreadyLikedThis');
  939. }
  940. },
  941. likePhotoWithKey: function () {
  942. if (this.isShowingLikePhotoConfirmation) return;
  943. if (this.skipLikePhotoConfirmation) {
  944. this.likePhoto();
  945. } else h.send(new i('/photos/confirm_like.php'), function (wa) {
  946. this.isShowingLikePhotoConfirmation = true;
  947. wa.subscribe('confirm', this.onCloseLikePhotoConfirmDialog.bind(this));
  948. wa.subscribe('cancel', this.onCloseLikePhotoConfirmDialog.bind(this));
  949. }.bind(this));
  950. return false;
  951. },
  952. likePhotoSkipConfirmation: function (wa) {
  953. this.skipLikePhotoConfirmation = wa;
  954. this.likePhoto();
  955. },
  956. onCloseLikePhotoConfirmDialog: function () {
  957. this.isShowingLikePhotoConfirmation = false;
  958. },
  959. updateTagBox: function (wa, xa) {
  960. this.unhiliteAllTags();
  961. var ya = qa(wa);
  962. if (!ya) return;
  963. l.addClass(ya, 'tagBox');
  964. l.addClass(ya, 'tagBoxPendingResponse');
  965. l.removeClass(ya, 'tagBoxPending');
  966. l.hide(n.find(ya, 'span.tagForm'));
  967. if (xa) {
  968. l.show(n.find(ya, 'span.tagApproved'));
  969. } else l.show(n.find(ya, 'span.tagIgnored'));
  970. },
  971. rotate: function (wa) {
  972. var xa = this.stream.getCursor();
  973. if (this.getVideoOnStage()) {
  974. var ya = (wa == 'left') ? 270 : 90;
  975. j.loadModules(['VideoRotate'], function (ab) {
  976. new ab(xa).motionRotate(ya);
  977. });
  978. return;
  979. }
  980. var za = ma({
  981. fbid: xa,
  982. cs_ver: w.VIEWER_SNOWLIFT
  983. }, this.stream.getPhotoSetQuery());
  984. za[wa] = 1;
  985. this.setLoadingState(va.STATE_IMAGE_DATA, true);
  986. this.setLoadingState(this.STATE_IMAGE_PIXELS, true);
  987. l.hide(this.image);
  988. new i('/ajax/photos/photo/rotate/').setAllowCrossPageTransition(true).setData(za).setErrorHandler(this.rotationError.bind(this, xa)).setFinallyHandler(this.rotationComplete.bind(this, xa)).setMethod('POST').setReadOnly(false).send();
  989. },
  990. rotationComplete: function (wa, xa) {
  991. if (wa == this.stream.getCursor()) {
  992. this.setLoadingState(va.STATE_IMAGE_DATA, false);
  993. this.switchImage(this.getImageURL(this.stream.getCurrentImageData()));
  994. this.swapData();
  995. }
  996. },
  997. rotationError: function (wa, xa) {
  998. if (wa == this.stream.getCursor()) {
  999. this.setLoadingState(va.STATE_IMAGE_DATA, false);
  1000. this.switchImage(this.getImageURL(this.stream.getCurrentImageData()));
  1001. j.loadModules(['AsyncResponse'], function (ya) {
  1002. ya.defaultErrorHandler(xa);
  1003. });
  1004. }
  1005. },
  1006. saveTagsFromPayload: function (wa) {
  1007. this.storeFromData(wa);
  1008. if ('data' in wa && this.stream.getCursor() in wa.data) this.swapData();
  1009. },
  1010. saveEdit: function () {
  1011. if (!l.hasClass(this.root, 'fbPhotoSnowliftEditMode')) return;
  1012. j.loadModules(['PhotoInlineEditor', 'Form'], function (wa, xa) {
  1013. var ya = wa.getInstance(this.getViewerConst());
  1014. ya && xa.bootstrap(ya.getForm().controller);
  1015. }.bind(this));
  1016. },
  1017. mouseLeaveListener: function (event) {
  1018. this.unhiliteAllTags();
  1019. this.reHilitePendingTag();
  1020. },
  1021. hilitePagerOnMouseMove: function (event) {
  1022. var wa = ja.getEventPosition(event),
  1023. xa = ja.getElementPosition(this.stage);
  1024. if (t.isRTL()) {
  1025. var ya = ja.getElementDimensions(this.stage);
  1026. this.stagePagerPrev = ya.x - (wa.x - xa.x) < va.GOPREV_AREA;
  1027. } else this.stagePagerPrev = wa.x - xa.x < va.GOPREV_AREA;
  1028. l.conditionClass(this.prevPager, 'hilightPager', this.stagePagerPrev);
  1029. l.conditionClass(this.nextPager, 'hilightPager', !this.stagePagerPrev);
  1030. var za, ab = event.getTarget();
  1031. if (!v.byClass(ab, 'snowliftOverlay') && !v.byClass(ab, 'bottomBarActions') && !v.byClass(ab, 'snowliftPager')) za = va.PAGER_FADE;
  1032. this.showPagers(za);
  1033. },
  1034. showPagers: function (wa) {
  1035. clearTimeout(this.fadePagerTimer);
  1036. this.setStagePagersState('active');
  1037. if (typeof wa !== 'undefined') this.fadePagerTimer = this.hidePagers.bind(this).defer(wa);
  1038. },
  1039. hidePagers: function () {
  1040. var wa = n.scry(this.getRoot(), '.fbPhotosPhotoActionsMenu')[0];
  1041. if (wa) return;
  1042. clearTimeout(this.fadePagerTimer);
  1043. this.setStagePagersState('inactive');
  1044. },
  1045. getTagger: function () {
  1046. if (!this.PhotoTagger) return null;
  1047. var wa = this.PhotoTagger.getInstance(w.VIEWER_SNOWLIFT);
  1048. if (!wa || !wa.tagHoverFacebox) return null;
  1049. return wa;
  1050. },
  1051. unhiliteAllTags: function () {
  1052. n.scry(this.stage, 'div.tagsWrapper div.hover').forEach(function (xa) {
  1053. l.removeClass(xa, 'hover');
  1054. });
  1055. this.hilitedTag = null;
  1056. if (!l.hasClass(this.root, 'taggingMode')) {
  1057. var wa = this.getTagger();
  1058. if (wa) {
  1059. wa.hideTagger();
  1060. wa.setCurrentFacebox(null);
  1061. }
  1062. }
  1063. },
  1064. switchHilitedTags: function (wa, xa) {
  1065. if (this.switchTimer !== null) {
  1066. clearTimeout(this.switchTimer);
  1067. this.switchTimer = null;
  1068. }
  1069. this.unhiliteAllTags();
  1070. var ya = qa(wa);
  1071. if (ya) {
  1072. this.hilitedTag = wa;
  1073. if (!l.hasClass(this.root, 'taggingMode') && aa.isFacebox(this.hilitedTag)) {
  1074. var za = this.getTagger();
  1075. if (za) {
  1076. l.addClass(ya, 'hover');
  1077. var ab = za.getFacebox(wa);
  1078. za.setCurrentFacebox(ab);
  1079. if (ab) za.addTagFromFacebox(ab);
  1080. }
  1081. } else l.addClass(ya, 'hover');
  1082. if (l.hasClass(ya, 'tagBoxPending') && !l.hasClass(ya, 'showPendingTagName') && xa === true) {
  1083. n.scry(this.stage, 'div.tagsWrapper div.showPendingTagName').forEach(function (bb) {
  1084. l.removeClass(bb, 'showPendingTagName');
  1085. });
  1086. l.addClass(ya, 'showPendingTagName');
  1087. }
  1088. }
  1089. },
  1090. reHilitePendingTag: function () {
  1091. var wa = qa(this.hilitedTag);
  1092. if (wa && l.hasClass(wa, 'showPendingTagName')) return;
  1093. var xa = n.scry(this.stage, 'div.tagsWrapper div.showPendingTagName')[0];
  1094. if (xa) this.switchHilitedTags(xa.id);
  1095. },
  1096. hiliteTagsOnMouseMove: function (event) {
  1097. if (!this.stream.getCurrentExtraData() || this.getVideoOnStage()) return;
  1098. if (this.switchTimer !== null) return;
  1099. var wa = event.getTarget();
  1100. if (v.byClass(wa, 'snowliftOverlay') || v.byClass(wa, 'fbPhotoSnowliftTagApproval') || v.byClass(wa, 'tagPointer') || v.byClass(wa, 'photoTagTypeahead')) return;
  1101. var xa = v.byClass(wa, 'tagBoxPending'),
  1102. ya = false;
  1103. if (this.hilitedTag) {
  1104. var za = qa(this.hilitedTag);
  1105. ya = za && l.hasClass(za, 'tagBoxPending');
  1106. }
  1107. var ab = ((!this.hilitedTag && xa) || (!ya && xa));
  1108. if (ab) {
  1109. this.switchHilitedTags(xa.id);
  1110. return;
  1111. }
  1112. if (xa && (xa.id == this.hilitedTag)) return;
  1113. var bb = 250,
  1114. cb = aa.absoluteToNormalizedPosition(this.image, ja.getEventPosition(event));
  1115. if (this.currentTagHasPrecedence(cb)) return;
  1116. var db = aa.getNearestBox(this.stream.getCurrentExtraData().tagRects, cb);
  1117. if (!db) {
  1118. if (!ya) {
  1119. this.unhiliteAllTags();
  1120. this.reHilitePendingTag();
  1121. }
  1122. return;
  1123. }
  1124. var eb = null;
  1125. if (ya) {
  1126. var fb = {};
  1127. fb[this.hilitedTag] = this.stream.getCurrentExtraData().tagRects[this.hilitedTag];
  1128. eb = aa.getNearestBox(fb, cb);
  1129. }
  1130. if (eb !== null && ya) return;
  1131. if (this.hilitedTag != db) if (ya) {
  1132. this.switchTimer = this.switchHilitedTags.bind(this, db).defer(bb);
  1133. } else {
  1134. if (this.showHover) {
  1135. if (!this.seenTags) this.seenTags = [];
  1136. if (!this.seenTags[db]) {
  1137. x.addFaceTagImpression();
  1138. this.seenTags[db] = true;
  1139. }
  1140. }
  1141. this.switchHilitedTags(db);
  1142. }
  1143. },
  1144. currentTagHasPrecedence: function (wa) {
  1145. if (!this.hilitedTag) return false;
  1146. var xa = this.stream.getCurrentExtraData().tagRects[this.hilitedTag],
  1147. ya = new ca(xa.t + (xa.h() / 2), xa.r, xa.b + (aa.isFacebox(this.hilitedTag) ? 10 : 0), xa.l, xa.domain);
  1148. return ya.contains(wa);
  1149. },
  1150. getVideoOnStage: function () {
  1151. var wa = this.stream && this.stream.getCurrentImageData();
  1152. return wa && wa.video;
  1153. },
  1154. shouldPageOnAction: function (wa, xa) {
  1155. if (!this.isOpen || this.isShowingLikePhotoConfirmation) return false;
  1156. var ya = n.isNode(xa) && (v.byClass(xa, 'snowliftPager') || v.byClass(xa, 'stagePagers') || v.byClass(xa, 'pivotPageColumn')),
  1157. za = n.isNode(xa) && v.byClass(xa, 'stage'),
  1158. ab = l.hasClass(xa, 'faceBox'),
  1159. bb = ((za && l.hasClass(this.root, 'taggingMode')) || v.byClass(xa, 'tagBoxPending') || v.byClass(xa, 'tagBoxPendingResponse') || v.byClass(xa, 'fbPhotoTagApprovalBox') || v.byClass(xa, 'tag') || (this.cropper && this.cropper.croppingMode));
  1160. if (bb) return false;
  1161. return wa == r.LEFT || wa == r.RIGHT || (!l.hasClass(this.root, 'taggingMode') && ab) || ya || za;
  1162. },
  1163. keyHandler: function (wa, event) {
  1164. if (event.getModifiers().any) return true;
  1165. switch (Event.getKeyCode(event)) {
  1166. case r.LEFT:
  1167. case r.RIGHT:
  1168. this.pageListener(event);
  1169. return false;
  1170. case 76:
  1171. return this.likePhotoWithKey();
  1172. }
  1173. },
  1174. pageListener: function (event) {
  1175. var wa = Event.getKeyCode(event),
  1176. xa = event.getTarget();
  1177. if (!this.shouldPageOnAction(wa, xa)) return;
  1178. var ya = 0;
  1179. if (wa == r.RIGHT) {
  1180. ya = 1;
  1181. x.setPagingAction('key_right');
  1182. } else if (wa == r.LEFT) {
  1183. ya = -1;
  1184. x.setPagingAction('key_left');
  1185. } else if (v.byClass(xa, 'next')) {
  1186. ya = 1;
  1187. x.setPagingAction('click_next');
  1188. } else if (v.byClass(xa, 'prev')) {
  1189. ya = -1;
  1190. x.setPagingAction('click_prev');
  1191. } else if (!this.stagePagerPrev) {
  1192. ya = 1;
  1193. x.setPagingAction('click_stage');
  1194. } else {
  1195. ya = -1;
  1196. x.setPagingAction('click_stage_back');
  1197. }
  1198. if (l.hasClass(this.root, 'fbPhotoSnowliftEditMode') || (this.cropper && this.cropper.croppingMode)) {
  1199. this.warnLeavePage(ya);
  1200. } else {
  1201. this.page(ya, ia.chrome() && p.isFullScreen());
  1202. ta('snowlift', xa, event).uai(x.pagingAction);
  1203. }
  1204. },
  1205. warnLeavePage: function (wa) {
  1206. new m().setTitle("Are you sure you want to leave this page?").setBody("You have unsaved changes that will be lost if you leave the page.").setButtons([{
  1207. name: 'leave_page',
  1208. label: "Leave this page",
  1209. handler: this.page.bind(this, wa)
  1210. }, {
  1211. name: 'continue_editing',
  1212. label: "Stay on this page",
  1213. className: 'inputaux'
  1214. }]).setModal(true).show();
  1215. },
  1216. page: function (wa, xa) {
  1217. if (!this.stream.isValidMovement(wa)) {
  1218. this.showPagers(va.PAGER_FADE);
  1219. return;
  1220. }
  1221. this.lastPage = Date.now();
  1222. this.unhiliteAllTags();
  1223. this.seenTags = [];
  1224. var ya = this.getVideoOnStage();
  1225. if (ya) this.switchVideo(ya, false);
  1226. if (this.pivots && this.pivots.page(wa)) return;
  1227. g.inform('PhotoSnowlift.PAGE');
  1228. fa.hide();
  1229. this.recacheData();
  1230. this.stream.moveCursor(wa);
  1231. l.hide(this.image);
  1232. if (this.stream.errorInCurrent()) {
  1233. this.setLoadingState(va.STATE_HTML, true);
  1234. l.show(this.errorBox);
  1235. return;
  1236. }
  1237. var za = this.stream.getCurrentImageData();
  1238. if (za) {
  1239. var ab = this.getImageURL(za);
  1240. if (ab) {
  1241. this.switchImage(ab, null, true);
  1242. } else if (za.video) this.switchVideo(za.video, true);
  1243. if (!xa) {
  1244. this.replaceUrl = true;
  1245. ra(za.info.permalink);
  1246. }
  1247. this.setLoadingState(va.STATE_IMAGE_DATA, false);
  1248. } else {
  1249. this.setLoadingState(va.STATE_IMAGE_PIXELS, true);
  1250. this.setLoadingState(va.STATE_IMAGE_DATA, true);
  1251. }
  1252. if (this.stream.getCurrentHtml()) {
  1253. this.swapData();
  1254. } else this.setLoadingState(va.STATE_HTML, true);
  1255. this.disableAds = this.disableAdsForSession;
  1256. this.loadAds();
  1257. if (this.cropper) this.cropper.resetPhoto();
  1258. },
  1259. logImpressionDetailsForPhoto: function () {
  1260. var wa = [].concat(n.scry(ka('fbPhotoSnowliftTagList'), 'input.photoImpressionDetails'), n.scry(ka('fbPhotoSnowliftFeedback'), 'input.photoImpressionDetails'));
  1261. if (wa.length === 0) return;
  1262. var xa = {};
  1263. for (var ya = 0; ya < wa.length; ya++) xa[wa[ya].name] = wa[ya].value;
  1264. if (this.getVideoOnStage()) {
  1265. xa.width = 0;
  1266. xa.height = 0;
  1267. } else {
  1268. var za = this.getImageDimensions(this.stream.getCurrentImageData());
  1269. xa.width = za.x;
  1270. xa.height = za.y;
  1271. }
  1272. x.addDetailData(this.stream.getCursor(), xa);
  1273. y.setIsLogAdData(true);
  1274. },
  1275. loadAds: function () {
  1276. if (this.disableAds) return;
  1277. y.loadAdsFromUserActivity();
  1278. },
  1279. transitionHandler: function (wa) {
  1280. if (wa.getQueryData().closeTheater || wa.getQueryData().permPage || wa.getQueryData().makeprofile || this.returningToStart) {
  1281. if (this.isOpen) this.close();
  1282. this.transitionHandlerRegistered = false;
  1283. return false;
  1284. }
  1285. if (this.replaceUrl) {
  1286. this.replaceUrl = false;
  1287. this._uriStack.push(wa.getQualifiedURI().toString());
  1288. u.transitionComplete(true);
  1289. return true;
  1290. }
  1291. var xa = this._uriStack.length;
  1292. if (xa >= 2 && this._uriStack[xa - 2] == wa.getQualifiedURI().toString()) this._uriStack.pop();
  1293. var ya = this.stream.getCursorForURI(wa.getUnqualifiedURI().toString());
  1294. if (ya) {
  1295. var za = this.stream.getRelativeMovement(ya);
  1296. this.page(za, true);
  1297. u.transitionComplete(false);
  1298. return true;
  1299. }
  1300. if (this.isOpen) {
  1301. u.transitionComplete(true);
  1302. this.close();
  1303. return true;
  1304. }
  1305. this.transitionHandlerRegistered = false;
  1306. return false;
  1307. },
  1308. recacheData: function () {
  1309. if (!this.loadingStates.html) {
  1310. var wa = this.stream.getCurrentHtml();
  1311. for (var xa in wa) {
  1312. wa[xa] = na(ka(xa).childNodes);
  1313. n.empty(ka(xa));
  1314. }
  1315. }
  1316. },
  1317. reloadIfTimeout: function () {
  1318. if (!q.hasLoaded(this.image)) {
  1319. var wa = this.makeNewImage(this.image.src, true);
  1320. Event.listen(wa, 'load', this.useImage.bind(this, wa, null, true));
  1321. }
  1322. },
  1323. useImage: function (wa, xa, ya) {
  1324. if (ya && q.hasLoaded(this.image)) return;
  1325. n.replace(this.image, wa);
  1326. this.image = wa;
  1327. g.inform('Amoeba/instrument', [this.image, 'image'], g.BEHAVIOR_PERSISTENT);
  1328. this.adjustStageSize(xa);
  1329. },
  1330. makeNewImage: function (wa, xa) {
  1331. if (this.imageLoadingTimer) {
  1332. clearTimeout(this.imageLoadingTimer);
  1333. this.imageLoadingTimer = null;
  1334. } else if (!xa) this.imageRefreshTimer = setTimeout(this.reloadIfTimeout.bind(this), va.LOADING_TIMEOUT);
  1335. var ya = n.create('img', {
  1336. className: 'spotlight',
  1337. alt: ''
  1338. });
  1339. ya.setAttribute('aria-describedby', 'fbPhotosSnowliftCaption');
  1340. ya.setAttribute('aria-busy', 'true');
  1341. Event.listen(ya, 'load', a.async_callback(function () {
  1342. clearTimeout(this.imageRefreshTimer);
  1343. this.image.setAttribute('aria-busy', 'false');
  1344. this.setLoadingState(this.STATE_IMAGE_PIXELS, false);
  1345. (function () {
  1346. if (this.isOpen) {
  1347. this.adjustStageSize();
  1348. this.adjustForNewData();
  1349. }
  1350. }).bind(this).defer();
  1351. }.bind(this), 'photo_theater'));
  1352. ya.src = wa;
  1353. return ya;
  1354. },
  1355. switchImage: function (wa, xa, ya) {
  1356. l.hide(this.image);
  1357. l.hide(this.errorBox);
  1358. this.setLoadingState(this.STATE_IMAGE_PIXELS, true);
  1359. var za = this.stream && this.stream.getCurrentImageData();
  1360. if (za) x.addPhotoView(za.info, this.shouldShowHiRes(za), this.fullscreen && p.isFullScreen());
  1361. this.useImage(this.makeNewImage(wa, false), xa, false);
  1362. if (ya) this.stream.preloadImages(this.shouldShowHiRes(za));
  1363. if (this.cropper && this.cropper.croppingMode) this.cropper.resetPhoto();
  1364. g.inform('PhotoSnowlift.SWITCH_IMAGE');
  1365. },
  1366. switchVideo: function (wa, xa) {
  1367. var ya = 'swf_' + wa;
  1368. if (xa) {
  1369. l.addClass(this.stageWrapper, 'showVideo');
  1370. var za = n.create('div', {
  1371. className: 'videoStageContainer'
  1372. });
  1373. n.appendContent(this.videoStage, za);
  1374. za.id = wa;
  1375. if (window[ya] && !qa(ya)) window[ya].write(wa);
  1376. this.adjustStageSizeForVideo.bind(this, ya).defer();
  1377. } else {
  1378. window[ya] && window[ya].addVariable('video_autoplay', 0);
  1379. this.videoLoadTimer && clearTimeout(this.videoLoadTimer);
  1380. n.empty(this.videoStage);
  1381. l.removeClass(this.stageWrapper, 'showVideo');
  1382. }
  1383. },
  1384. checkVideoStatus: function (wa) {
  1385. if (this.videoLoadTimer) clearTimeout(this.videoLoadTimer);
  1386. var xa = this.getVideoOnStage();
  1387. if (!xa) {
  1388. return;
  1389. } else {
  1390. var ya = 'swf_' + xa;
  1391. if (wa !== ya) return;
  1392. this.adjustStageSizeForVideo(wa);
  1393. }
  1394. },
  1395. adjustStageSizeForVideo: function (wa) {
  1396. var xa = qa(wa);
  1397. if (!xa) {
  1398. this.videoLoadTimer = setTimeout(this.checkVideoStatus.bind(this, wa), 200);
  1399. } else this.adjustStageSize(new ja(xa.width, xa.height));
  1400. },
  1401. handleServerError: function (wa, xa) {
  1402. n.setContent(this.errorBox, wa);
  1403. this.storeFromData(xa);
  1404. },
  1405. swapData: function () {
  1406. var wa, xa = this.stream.getCurrentHtml();
  1407. if (xa) {
  1408. this.setLoadingState(va.STATE_HTML, false);
  1409. for (var ya in xa) {
  1410. wa = qa(ya);
  1411. wa && n.setContent(wa, xa[ya]);
  1412. }
  1413. g.inform('PhotoSnowlift.DATA_CHANGE', this.stream.getCurrentImageData().info, g.BEHAVIOR_STATE);
  1414. if (this.stream.getCurrentExtraData()) g.inform('PhotoSnowlift.EXTRA_DATA_CHANGE', this.stream.getCurrentExtraData(), g.BEHAVIOR_STATE);
  1415. }
  1416. this.showPagers(va.PAGER_FADE);
  1417. this.adjustScroller();
  1418. this.scrollableArea.showScrollbar(false);
  1419. this.adjustForNewData();
  1420. this.logImpressionDetailsForPhoto();
  1421. },
  1422. updateTotalCount: function (wa, xa, ya) {
  1423. var za = this.stream.getCurrentHtml();
  1424. if (za) {
  1425. var ab = ka('fbPhotoSnowliftPositionAndCount');
  1426. n.replace(ab, ya);
  1427. ab = ya;
  1428. l.show(ab);
  1429. var bb = 'fbPhotoSnowliftPositionAndCount';
  1430. za[bb] = na(ab.childNodes);
  1431. }
  1432. this.stream.setTotalCount(wa);
  1433. this.stream.setFirstCursorIndex(xa);
  1434. },
  1435. addPhotoFbids: function (wa, xa, ya, za) {
  1436. if (za && this.sessionID && za != this.sessionID) return;
  1437. var ab = this.stream.getCursor() === null;
  1438. this.stream.attachToFbidsList(wa, xa, ya);
  1439. if (ya && ab) this.page(0, true);
  1440. if (this.pivots && ya) this.pivots.setCycleCount(this.stream.calculateDistance(this.stream.getCursor(), this.stream.firstCursor));
  1441. if (!this.pagersShown && this.stream.canPage()) this.setStagePagersState('ready');
  1442. },
  1443. attachTagger: function (wa) {
  1444. n.appendContent(this.stageActions, wa);
  1445. },
  1446. storeFromData: function (wa) {
  1447. if (!this.isOpen) return;
  1448. if (wa.ssid && this.sessionID && this.sessionID != wa.ssid) return;
  1449. var xa = this.stream.storeToCache(wa);
  1450. if ('error' in xa) {
  1451. this.checkState(va.STATE_ERROR);
  1452. return;
  1453. }
  1454. if ('init' in xa) {
  1455. this.initDataFetched(xa.init);
  1456. if (this.openExplicitly) {
  1457. this.replaceUrl = true;
  1458. ra(this.stream.getCurrentImageData().info.permalink);
  1459. }
  1460. if (this.stream.canPage()) this.setStagePagersState('ready');
  1461. this.ua && this.ua.add_event('ufi');
  1462. }
  1463. if ('image' in xa) this.checkState(va.STATE_IMAGE_DATA);
  1464. if ('data' in xa) this.checkState(va.STATE_HTML);
  1465. },
  1466. setStagePagersState: function (wa) {
  1467. switch (wa) {
  1468. case 'ready':
  1469. l.addClass(this.root, 'pagingReady');
  1470. this.pagersShown = true;
  1471. this.ua && this.ua.add_event('arrows');
  1472. return;
  1473. case 'active':
  1474. l.addClass(this.root, 'pagingActivated');
  1475. return;
  1476. case 'inactive':
  1477. l.removeClass(this.root, 'pagingActivated');
  1478. return;
  1479. case 'disabled':
  1480. case 'reset':
  1481. l.removeClass(this.root, 'pagingReady');
  1482. return;
  1483. }
  1484. },
  1485. deletePhoto: function (wa) {
  1486. this.closeRefresh();
  1487. },
  1488. closeRefresh: function () {
  1489. this.refreshOnClose = true;
  1490. this.closeHandler();
  1491. },
  1492. onHiliteTag: function (wa, xa) {
  1493. if (xa.version != w.VIEWER_SNOWLIFT) return;
  1494. var ya = xa.tag;
  1495. if (ya) this.switchHilitedTags(ya, true);
  1496. },
  1497. onUpdateTagBox: function (wa, xa) {
  1498. if (xa.version == w.VIEWER_SNOWLIFT) this.updateTagBox(xa.id, xa.approve);
  1499. }
  1500. });
  1501. e.exports = va;
  1502. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement