all.js 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. /* ---- plugins/Sidebar/media/Class.coffee ---- */
  2. (function() {
  3. var Class,
  4. __slice = [].slice;
  5. Class = (function() {
  6. function Class() {}
  7. Class.prototype.trace = true;
  8. Class.prototype.log = function() {
  9. var args;
  10. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  11. if (!this.trace) {
  12. return;
  13. }
  14. if (typeof console === 'undefined') {
  15. return;
  16. }
  17. args.unshift("[" + this.constructor.name + "]");
  18. console.log.apply(console, args);
  19. return this;
  20. };
  21. Class.prototype.logStart = function() {
  22. var args, name;
  23. name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  24. if (!this.trace) {
  25. return;
  26. }
  27. this.logtimers || (this.logtimers = {});
  28. this.logtimers[name] = +(new Date);
  29. if (args.length > 0) {
  30. this.log.apply(this, ["" + name].concat(__slice.call(args), ["(started)"]));
  31. }
  32. return this;
  33. };
  34. Class.prototype.logEnd = function() {
  35. var args, ms, name;
  36. name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  37. ms = +(new Date) - this.logtimers[name];
  38. this.log.apply(this, ["" + name].concat(__slice.call(args), ["(Done in " + ms + "ms)"]));
  39. return this;
  40. };
  41. return Class;
  42. })();
  43. window.Class = Class;
  44. }).call(this);
  45. /* ---- plugins/Sidebar/media/RateLimit.coffee ---- */
  46. (function() {
  47. var call_after_interval, limits;
  48. limits = {};
  49. call_after_interval = {};
  50. window.RateLimit = function(interval, fn) {
  51. if (!limits[fn]) {
  52. call_after_interval[fn] = false;
  53. fn();
  54. return limits[fn] = setTimeout((function() {
  55. if (call_after_interval[fn]) {
  56. fn();
  57. }
  58. delete limits[fn];
  59. return delete call_after_interval[fn];
  60. }), interval);
  61. } else {
  62. return call_after_interval[fn] = true;
  63. }
  64. };
  65. }).call(this);
  66. /* ---- plugins/Sidebar/media/Scrollable.js ---- */
  67. /* via http://jsfiddle.net/elGrecode/00dgurnn/ */
  68. window.initScrollable = function () {
  69. var scrollContainer = document.querySelector('.scrollable'),
  70. scrollContentWrapper = document.querySelector('.scrollable .content-wrapper'),
  71. scrollContent = document.querySelector('.scrollable .content'),
  72. contentPosition = 0,
  73. scrollerBeingDragged = false,
  74. scroller,
  75. topPosition,
  76. scrollerHeight;
  77. function calculateScrollerHeight() {
  78. // *Calculation of how tall scroller should be
  79. var visibleRatio = scrollContainer.offsetHeight / scrollContentWrapper.scrollHeight;
  80. if (visibleRatio == 1)
  81. scroller.style.display = "none";
  82. else
  83. scroller.style.display = "block";
  84. return visibleRatio * scrollContainer.offsetHeight;
  85. }
  86. function moveScroller(evt) {
  87. // Move Scroll bar to top offset
  88. var scrollPercentage = evt.target.scrollTop / scrollContentWrapper.scrollHeight;
  89. topPosition = scrollPercentage * (scrollContainer.offsetHeight - 5); // 5px arbitrary offset so scroll bar doesn't move too far beyond content wrapper bounding box
  90. scroller.style.top = topPosition + 'px';
  91. }
  92. function startDrag(evt) {
  93. normalizedPosition = evt.pageY;
  94. contentPosition = scrollContentWrapper.scrollTop;
  95. scrollerBeingDragged = true;
  96. window.addEventListener('mousemove', scrollBarScroll);
  97. return false;
  98. }
  99. function stopDrag(evt) {
  100. scrollerBeingDragged = false;
  101. window.removeEventListener('mousemove', scrollBarScroll);
  102. }
  103. function scrollBarScroll(evt) {
  104. if (scrollerBeingDragged === true) {
  105. evt.preventDefault();
  106. var mouseDifferential = evt.pageY - normalizedPosition;
  107. var scrollEquivalent = mouseDifferential * (scrollContentWrapper.scrollHeight / scrollContainer.offsetHeight);
  108. scrollContentWrapper.scrollTop = contentPosition + scrollEquivalent;
  109. }
  110. }
  111. function updateHeight() {
  112. scrollerHeight = calculateScrollerHeight() - 10;
  113. scroller.style.height = scrollerHeight + 'px';
  114. }
  115. function createScroller() {
  116. // *Creates scroller element and appends to '.scrollable' div
  117. // create scroller element
  118. scroller = document.createElement("div");
  119. scroller.className = 'scroller';
  120. // determine how big scroller should be based on content
  121. scrollerHeight = calculateScrollerHeight() - 10;
  122. if (scrollerHeight / scrollContainer.offsetHeight < 1) {
  123. // *If there is a need to have scroll bar based on content size
  124. scroller.style.height = scrollerHeight + 'px';
  125. // append scroller to scrollContainer div
  126. scrollContainer.appendChild(scroller);
  127. // show scroll path divot
  128. scrollContainer.className += ' showScroll';
  129. // attach related draggable listeners
  130. scroller.addEventListener('mousedown', startDrag);
  131. window.addEventListener('mouseup', stopDrag);
  132. }
  133. }
  134. createScroller();
  135. // *** Listeners ***
  136. scrollContentWrapper.addEventListener('scroll', moveScroller);
  137. return updateHeight;
  138. };
  139. /* ---- plugins/Sidebar/media/Sidebar.coffee ---- */
  140. (function() {
  141. var Sidebar,
  142. __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  143. __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  144. __hasProp = {}.hasOwnProperty;
  145. Sidebar = (function(_super) {
  146. __extends(Sidebar, _super);
  147. function Sidebar() {
  148. this.unloadGlobe = __bind(this.unloadGlobe, this);
  149. this.displayGlobe = __bind(this.displayGlobe, this);
  150. this.loadGlobe = __bind(this.loadGlobe, this);
  151. this.animDrag = __bind(this.animDrag, this);
  152. this.setHtmlTag = __bind(this.setHtmlTag, this);
  153. this.waitMove = __bind(this.waitMove, this);
  154. this.resized = __bind(this.resized, this);
  155. this.tag = null;
  156. this.container = null;
  157. this.opened = false;
  158. this.width = 410;
  159. this.fixbutton = $(".fixbutton");
  160. this.fixbutton_addx = 0;
  161. this.fixbutton_initx = 0;
  162. this.fixbutton_targetx = 0;
  163. this.page_width = $(window).width();
  164. this.frame = $("#inner-iframe");
  165. this.initFixbutton();
  166. this.dragStarted = 0;
  167. this.globe = null;
  168. this.preload_html = null;
  169. this.original_set_site_info = wrapper.setSiteInfo;
  170. if (false) {
  171. this.startDrag();
  172. this.moved();
  173. this.fixbutton_targetx = this.fixbutton_initx - this.width;
  174. this.stopDrag();
  175. }
  176. }
  177. Sidebar.prototype.initFixbutton = function() {
  178. /*
  179. @fixbutton.on "mousedown touchstart", (e) =>
  180. if not @opened
  181. @logStart("Preloading")
  182. wrapper.ws.cmd "sidebarGetHtmlTag", {}, (res) =>
  183. @logEnd("Preloading")
  184. @preload_html = res
  185. */
  186. this.fixbutton.on("mousedown touchstart", (function(_this) {
  187. return function(e) {
  188. e.preventDefault();
  189. _this.fixbutton.off("click touchstop touchcancel");
  190. _this.fixbutton.off("mousemove touchmove");
  191. _this.dragStarted = +(new Date);
  192. return _this.fixbutton.one("mousemove touchmove", function(e) {
  193. var mousex;
  194. mousex = e.pageX;
  195. if (!mousex) {
  196. mousex = e.originalEvent.touches[0].pageX;
  197. }
  198. _this.fixbutton_addx = _this.fixbutton.offset().left - mousex;
  199. return _this.startDrag();
  200. });
  201. };
  202. })(this));
  203. this.fixbutton.parent().on("click touchstop touchcancel", (function(_this) {
  204. return function(e) {
  205. return _this.stopDrag();
  206. };
  207. })(this));
  208. this.resized();
  209. return $(window).on("resize", this.resized);
  210. };
  211. Sidebar.prototype.resized = function() {
  212. this.page_width = $(window).width();
  213. this.fixbutton_initx = this.page_width - 75;
  214. if (this.opened) {
  215. return this.fixbutton.css({
  216. left: this.fixbutton_initx - this.width
  217. });
  218. } else {
  219. return this.fixbutton.css({
  220. left: this.fixbutton_initx
  221. });
  222. }
  223. };
  224. Sidebar.prototype.startDrag = function() {
  225. this.log("startDrag");
  226. this.fixbutton_targetx = this.fixbutton_initx;
  227. this.fixbutton.addClass("dragging");
  228. $("<div class='drag-bg'></div>").appendTo(document.body);
  229. if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) {
  230. this.fixbutton.css("pointer-events", "none");
  231. }
  232. this.fixbutton.one("click", (function(_this) {
  233. return function(e) {
  234. _this.stopDrag();
  235. _this.fixbutton.removeClass("dragging");
  236. if (Math.abs(_this.fixbutton.offset().left - _this.fixbutton_initx) > 5) {
  237. return e.preventDefault();
  238. }
  239. };
  240. })(this));
  241. this.fixbutton.parents().on("mousemove touchmove", this.animDrag);
  242. this.fixbutton.parents().on("mousemove touchmove", this.waitMove);
  243. return this.fixbutton.parents().on("mouseup touchstop touchend touchcancel", (function(_this) {
  244. return function(e) {
  245. e.preventDefault();
  246. return _this.stopDrag();
  247. };
  248. })(this));
  249. };
  250. Sidebar.prototype.waitMove = function(e) {
  251. if (Math.abs(this.fixbutton.offset().left - this.fixbutton_targetx) > 10 && (+(new Date)) - this.dragStarted > 100) {
  252. this.moved();
  253. return this.fixbutton.parents().off("mousemove touchmove", this.waitMove);
  254. }
  255. };
  256. Sidebar.prototype.moved = function() {
  257. var img;
  258. this.log("Moved");
  259. this.createHtmltag();
  260. $(document.body).css("perspective", "1000px").addClass("body-sidebar");
  261. $(window).off("resize");
  262. $(window).on("resize", (function(_this) {
  263. return function() {
  264. $(document.body).css("height", $(window).height());
  265. _this.scrollable();
  266. return _this.resized();
  267. };
  268. })(this));
  269. $(window).trigger("resize");
  270. wrapper.setSiteInfo = (function(_this) {
  271. return function(site_info) {
  272. _this.setSiteInfo(site_info);
  273. return _this.original_set_site_info.apply(wrapper, arguments);
  274. };
  275. })(this);
  276. img = new Image();
  277. return img.src = "/uimedia/globe/world.jpg";
  278. };
  279. Sidebar.prototype.setSiteInfo = function(site_info) {
  280. RateLimit(1500, (function(_this) {
  281. return function() {
  282. return _this.updateHtmlTag();
  283. };
  284. })(this));
  285. return RateLimit(30000, (function(_this) {
  286. return function() {
  287. return _this.displayGlobe();
  288. };
  289. })(this));
  290. };
  291. Sidebar.prototype.createHtmltag = function() {
  292. this.when_loaded = $.Deferred();
  293. if (!this.container) {
  294. this.container = $("<div class=\"sidebar-container\"><div class=\"sidebar scrollable\"><div class=\"content-wrapper\"><div class=\"content\">\n</div></div></div></div>");
  295. this.container.appendTo(document.body);
  296. this.tag = this.container.find(".sidebar");
  297. this.updateHtmlTag();
  298. return this.scrollable = window.initScrollable();
  299. }
  300. };
  301. Sidebar.prototype.updateHtmlTag = function() {
  302. if (this.preload_html) {
  303. this.setHtmlTag(this.preload_html);
  304. return this.preload_html = null;
  305. } else {
  306. return wrapper.ws.cmd("sidebarGetHtmlTag", {}, this.setHtmlTag);
  307. }
  308. };
  309. Sidebar.prototype.setHtmlTag = function(res) {
  310. if (this.tag.find(".content").children().length === 0) {
  311. this.log("Creating content");
  312. this.container.addClass("loaded");
  313. morphdom(this.tag.find(".content")[0], '<div class="content">' + res + '</div>');
  314. return this.when_loaded.resolve();
  315. } else {
  316. this.log("Patching content");
  317. return morphdom(this.tag.find(".content")[0], '<div class="content">' + res + '</div>', {
  318. onBeforeMorphEl: function(from_el, to_el) {
  319. if (from_el.className === "globe" || from_el.className.indexOf("noupdate") >= 0) {
  320. return false;
  321. } else {
  322. return true;
  323. }
  324. }
  325. });
  326. }
  327. };
  328. Sidebar.prototype.animDrag = function(e) {
  329. var mousex, overdrag, overdrag_percent, targetx;
  330. mousex = e.pageX;
  331. if (!mousex) {
  332. mousex = e.originalEvent.touches[0].pageX;
  333. }
  334. overdrag = this.fixbutton_initx - this.width - mousex;
  335. if (overdrag > 0) {
  336. overdrag_percent = 1 + overdrag / 300;
  337. mousex = (mousex + (this.fixbutton_initx - this.width) * overdrag_percent) / (1 + overdrag_percent);
  338. }
  339. targetx = this.fixbutton_initx - mousex - this.fixbutton_addx;
  340. this.fixbutton[0].style.left = (mousex + this.fixbutton_addx) + "px";
  341. if (this.tag) {
  342. this.tag[0].style.transform = "translateX(" + (0 - targetx) + "px)";
  343. }
  344. if ((!this.opened && targetx > this.width / 3) || (this.opened && targetx > this.width * 0.9)) {
  345. return this.fixbutton_targetx = this.fixbutton_initx - this.width;
  346. } else {
  347. return this.fixbutton_targetx = this.fixbutton_initx;
  348. }
  349. };
  350. Sidebar.prototype.stopDrag = function() {
  351. var targetx;
  352. this.fixbutton.parents().off("mousemove touchmove");
  353. this.fixbutton.off("mousemove touchmove");
  354. this.fixbutton.css("pointer-events", "");
  355. $(".drag-bg").remove();
  356. if (!this.fixbutton.hasClass("dragging")) {
  357. return;
  358. }
  359. this.fixbutton.removeClass("dragging");
  360. if (this.fixbutton_targetx !== this.fixbutton.offset().left) {
  361. this.fixbutton.stop().animate({
  362. "left": this.fixbutton_targetx
  363. }, 500, "easeOutBack", (function(_this) {
  364. return function() {
  365. if (_this.fixbutton_targetx === _this.fixbutton_initx) {
  366. _this.fixbutton.css("left", "auto");
  367. } else {
  368. _this.fixbutton.css("left", _this.fixbutton_targetx);
  369. }
  370. return $(".fixbutton-bg").trigger("mouseout");
  371. };
  372. })(this));
  373. if (this.fixbutton_targetx === this.fixbutton_initx) {
  374. targetx = 0;
  375. this.opened = false;
  376. } else {
  377. targetx = this.width;
  378. if (!this.opened) {
  379. this.when_loaded.done((function(_this) {
  380. return function() {
  381. return _this.onOpened();
  382. };
  383. })(this));
  384. }
  385. this.opened = true;
  386. }
  387. this.tag.css("transition", "0.4s ease-out");
  388. this.tag.css("transform", "translateX(-" + targetx + "px)").one(transitionEnd, (function(_this) {
  389. return function() {
  390. _this.tag.css("transition", "");
  391. if (!_this.opened) {
  392. _this.container.remove();
  393. _this.container = null;
  394. _this.tag.remove();
  395. return _this.tag = null;
  396. }
  397. };
  398. })(this));
  399. this.log("stopdrag", "opened:", this.opened);
  400. if (!this.opened) {
  401. return this.onClosed();
  402. }
  403. }
  404. };
  405. Sidebar.prototype.onOpened = function() {
  406. this.log("Opened");
  407. this.scrollable();
  408. this.tag.find("#checkbox-owned").off("click").on("click", (function(_this) {
  409. return function() {
  410. return setTimeout((function() {
  411. return _this.scrollable();
  412. }), 300);
  413. };
  414. })(this));
  415. this.tag.find("#button-sitelimit").off("click").on("click", (function(_this) {
  416. return function() {
  417. wrapper.ws.cmd("siteSetLimit", $("#input-sitelimit").val(), function() {
  418. wrapper.notifications.add("done-sitelimit", "done", "Site storage limit modified!", 5000);
  419. return _this.updateHtmlTag();
  420. });
  421. return false;
  422. };
  423. })(this));
  424. this.tag.find("#button-dbreload").off("click").on("click", (function(_this) {
  425. return function() {
  426. wrapper.ws.cmd("dbReload", [], function() {
  427. wrapper.notifications.add("done-dbreload", "done", "Database schema reloaded", 5000);
  428. return _this.updateHtmlTag();
  429. });
  430. return false;
  431. };
  432. })(this));
  433. this.tag.find("#button-dbrebuild").off("click").on("click", (function(_this) {
  434. return function() {
  435. wrapper.notifications.add("done-dbrebuild", "info", "Database rebuilding....");
  436. wrapper.ws.cmd("dbRebuild", [], function() {
  437. wrapper.notifications.add("done-dbrebuild", "done", "Database rebuilt!", 5000);
  438. return _this.updateHtmlTag();
  439. });
  440. return false;
  441. };
  442. })(this));
  443. this.tag.find("#button-update").off("click").on("click", (function(_this) {
  444. return function() {
  445. _this.tag.find("#button-update").addClass("loading");
  446. wrapper.ws.cmd("siteUpdate", wrapper.site_info.address, function() {
  447. wrapper.notifications.add("done-updated", "done", "Site updated!", 5000);
  448. return _this.tag.find("#button-update").removeClass("loading");
  449. });
  450. return false;
  451. };
  452. })(this));
  453. this.tag.find("#button-pause").off("click").on("click", (function(_this) {
  454. return function() {
  455. _this.tag.find("#button-pause").addClass("hidden");
  456. wrapper.ws.cmd("sitePause", wrapper.site_info.address);
  457. return false;
  458. };
  459. })(this));
  460. this.tag.find("#button-resume").off("click").on("click", (function(_this) {
  461. return function() {
  462. _this.tag.find("#button-resume").addClass("hidden");
  463. wrapper.ws.cmd("siteResume", wrapper.site_info.address);
  464. return false;
  465. };
  466. })(this));
  467. this.tag.find("#button-delete").off("click").on("click", (function(_this) {
  468. return function() {
  469. wrapper.displayConfirm("Are you sure?", "Delete this site", function() {
  470. _this.tag.find("#button-delete").addClass("loading");
  471. return wrapper.ws.cmd("siteDelete", wrapper.site_info.address, function() {
  472. return document.location = $(".fixbutton-bg").attr("href");
  473. });
  474. });
  475. return false;
  476. };
  477. })(this));
  478. this.tag.find("#checkbox-owned").off("click").on("click", (function(_this) {
  479. return function() {
  480. return wrapper.ws.cmd("siteSetOwned", [_this.tag.find("#checkbox-owned").is(":checked")]);
  481. };
  482. })(this));
  483. this.tag.find("#checkbox-autodownloadoptional").off("click").on("click", (function(_this) {
  484. return function() {
  485. return wrapper.ws.cmd("siteSetAutodownloadoptional", [_this.tag.find("#checkbox-autodownloadoptional").is(":checked")]);
  486. };
  487. })(this));
  488. this.tag.find("#button-identity").off("click").on("click", (function(_this) {
  489. return function() {
  490. wrapper.ws.cmd("certSelect");
  491. return false;
  492. };
  493. })(this));
  494. this.tag.find("#checkbox-owned").off("click").on("click", (function(_this) {
  495. return function() {
  496. return wrapper.ws.cmd("siteSetOwned", [_this.tag.find("#checkbox-owned").is(":checked")]);
  497. };
  498. })(this));
  499. this.tag.find("#button-settings").off("click").on("click", (function(_this) {
  500. return function() {
  501. wrapper.ws.cmd("fileGet", "content.json", function(res) {
  502. var data, json_raw;
  503. data = JSON.parse(res);
  504. data["title"] = $("#settings-title").val();
  505. data["description"] = $("#settings-description").val();
  506. json_raw = unescape(encodeURIComponent(JSON.stringify(data, void 0, '\t')));
  507. return wrapper.ws.cmd("fileWrite", ["content.json", btoa(json_raw)], function(res) {
  508. if (res !== "ok") {
  509. return wrapper.notifications.add("file-write", "error", "File write error: " + res);
  510. } else {
  511. wrapper.notifications.add("file-write", "done", "Site settings saved!", 5000);
  512. return _this.updateHtmlTag();
  513. }
  514. });
  515. });
  516. return false;
  517. };
  518. })(this));
  519. this.tag.find("#button-sign").off("click").on("click", (function(_this) {
  520. return function() {
  521. var inner_path;
  522. inner_path = _this.tag.find("#input-contents").val();
  523. if (wrapper.site_info.privatekey) {
  524. wrapper.ws.cmd("siteSign", {
  525. privatekey: "stored",
  526. inner_path: inner_path,
  527. update_changed_files: true
  528. }, function(res) {
  529. return wrapper.notifications.add("sign", "done", inner_path + " Signed!", 5000);
  530. });
  531. } else {
  532. wrapper.displayPrompt("Enter your private key:", "password", "Sign", function(privatekey) {
  533. return wrapper.ws.cmd("siteSign", {
  534. privatekey: privatekey,
  535. inner_path: inner_path,
  536. update_changed_files: true
  537. }, function(res) {
  538. if (res === "ok") {
  539. return wrapper.notifications.add("sign", "done", inner_path + " Signed!", 5000);
  540. }
  541. });
  542. });
  543. }
  544. return false;
  545. };
  546. })(this));
  547. this.tag.find("#button-publish").off("click").on("click", (function(_this) {
  548. return function() {
  549. var inner_path;
  550. inner_path = _this.tag.find("#input-contents").val();
  551. _this.tag.find("#button-publish").addClass("loading");
  552. return wrapper.ws.cmd("sitePublish", {
  553. "inner_path": inner_path,
  554. "sign": false
  555. }, function() {
  556. return _this.tag.find("#button-publish").removeClass("loading");
  557. });
  558. };
  559. })(this));
  560. return this.loadGlobe();
  561. };
  562. Sidebar.prototype.onClosed = function() {
  563. $(window).off("resize");
  564. $(window).on("resize", this.resized);
  565. $(document.body).css("transition", "0.6s ease-in-out").removeClass("body-sidebar").on(transitionEnd, (function(_this) {
  566. return function(e) {
  567. if (e.target === document.body) {
  568. $(document.body).css("height", "auto").css("perspective", "").css("transition", "").off(transitionEnd);
  569. return _this.unloadGlobe();
  570. }
  571. };
  572. })(this));
  573. return wrapper.setSiteInfo = this.original_set_site_info;
  574. };
  575. Sidebar.prototype.loadGlobe = function() {
  576. console.log("loadGlobe", this.tag.find(".globe").hasClass("loading"));
  577. if (this.tag.find(".globe").hasClass("loading")) {
  578. return setTimeout(((function(_this) {
  579. return function() {
  580. if (typeof DAT === "undefined") {
  581. return $.getScript("/uimedia/globe/all.js", _this.displayGlobe);
  582. } else {
  583. return _this.displayGlobe();
  584. }
  585. };
  586. })(this)), 600);
  587. }
  588. };
  589. Sidebar.prototype.displayGlobe = function() {
  590. var img;
  591. img = new Image();
  592. img.src = "/uimedia/globe/world.jpg";
  593. return img.onload = (function(_this) {
  594. return function() {
  595. return wrapper.ws.cmd("sidebarGetPeers", [], function(globe_data) {
  596. var e, _ref, _ref1;
  597. if (_this.globe) {
  598. _this.globe.scene.remove(_this.globe.points);
  599. _this.globe.addData(globe_data, {
  600. format: 'magnitude',
  601. name: "hello",
  602. animated: false
  603. });
  604. _this.globe.createPoints();
  605. } else if (typeof DAT !== "undefined") {
  606. try {
  607. _this.globe = new DAT.Globe(_this.tag.find(".globe")[0], {
  608. "imgDir": "/uimedia/globe/"
  609. });
  610. _this.globe.addData(globe_data, {
  611. format: 'magnitude',
  612. name: "hello"
  613. });
  614. _this.globe.createPoints();
  615. _this.globe.animate();
  616. } catch (_error) {
  617. e = _error;
  618. console.log("WebGL error", e);
  619. if ((_ref = _this.tag) != null) {
  620. _ref.find(".globe").addClass("error").text("WebGL not supported");
  621. }
  622. }
  623. }
  624. return (_ref1 = _this.tag) != null ? _ref1.find(".globe").removeClass("loading") : void 0;
  625. });
  626. };
  627. })(this);
  628. };
  629. Sidebar.prototype.unloadGlobe = function() {
  630. if (!this.globe) {
  631. return false;
  632. }
  633. this.globe.unload();
  634. return this.globe = null;
  635. };
  636. return Sidebar;
  637. })(Class);
  638. setTimeout((function() {
  639. return window.sidebar = new Sidebar();
  640. }), 500);
  641. window.transitionEnd = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend';
  642. }).call(this);
  643. /* ---- plugins/Sidebar/media/morphdom.js ---- */
  644. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.morphdom = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  645. var specialElHandlers = {
  646. /**
  647. * Needed for IE. Apparently IE doesn't think
  648. * that "selected" is an attribute when reading
  649. * over the attributes using selectEl.attributes
  650. */
  651. OPTION: function(fromEl, toEl) {
  652. if ((fromEl.selected = toEl.selected)) {
  653. fromEl.setAttribute('selected', '');
  654. } else {
  655. fromEl.removeAttribute('selected', '');
  656. }
  657. },
  658. /**
  659. * The "value" attribute is special for the <input> element
  660. * since it sets the initial value. Changing the "value"
  661. * attribute without changing the "value" property will have
  662. * no effect since it is only used to the set the initial value.
  663. * Similar for the "checked" attribute.
  664. */
  665. /*INPUT: function(fromEl, toEl) {
  666. fromEl.checked = toEl.checked;
  667. fromEl.value = toEl.value;
  668. if (!toEl.hasAttribute('checked')) {
  669. fromEl.removeAttribute('checked');
  670. }
  671. if (!toEl.hasAttribute('value')) {
  672. fromEl.removeAttribute('value');
  673. }
  674. }*/
  675. };
  676. function noop() {}
  677. /**
  678. * Loop over all of the attributes on the target node and make sure the
  679. * original DOM node has the same attributes. If an attribute
  680. * found on the original node is not on the new node then remove it from
  681. * the original node
  682. * @param {HTMLElement} fromNode
  683. * @param {HTMLElement} toNode
  684. */
  685. function morphAttrs(fromNode, toNode) {
  686. var attrs = toNode.attributes;
  687. var i;
  688. var attr;
  689. var attrName;
  690. var attrValue;
  691. var foundAttrs = {};
  692. for (i=attrs.length-1; i>=0; i--) {
  693. attr = attrs[i];
  694. if (attr.specified !== false) {
  695. attrName = attr.name;
  696. attrValue = attr.value;
  697. foundAttrs[attrName] = true;
  698. if (fromNode.getAttribute(attrName) !== attrValue) {
  699. fromNode.setAttribute(attrName, attrValue);
  700. }
  701. }
  702. }
  703. // Delete any extra attributes found on the original DOM element that weren't
  704. // found on the target element.
  705. attrs = fromNode.attributes;
  706. for (i=attrs.length-1; i>=0; i--) {
  707. attr = attrs[i];
  708. if (attr.specified !== false) {
  709. attrName = attr.name;
  710. if (!foundAttrs.hasOwnProperty(attrName)) {
  711. fromNode.removeAttribute(attrName);
  712. }
  713. }
  714. }
  715. }
  716. /**
  717. * Copies the children of one DOM element to another DOM element
  718. */
  719. function moveChildren(from, to) {
  720. var curChild = from.firstChild;
  721. while(curChild) {
  722. var nextChild = curChild.nextSibling;
  723. to.appendChild(curChild);
  724. curChild = nextChild;
  725. }
  726. return to;
  727. }
  728. function morphdom(fromNode, toNode, options) {
  729. if (!options) {
  730. options = {};
  731. }
  732. if (typeof toNode === 'string') {
  733. var newBodyEl = document.createElement('body');
  734. newBodyEl.innerHTML = toNode;
  735. toNode = newBodyEl.childNodes[0];
  736. }
  737. var savedEls = {}; // Used to save off DOM elements with IDs
  738. var unmatchedEls = {};
  739. var onNodeDiscarded = options.onNodeDiscarded || noop;
  740. var onBeforeMorphEl = options.onBeforeMorphEl || noop;
  741. var onBeforeMorphElChildren = options.onBeforeMorphElChildren || noop;
  742. function removeNodeHelper(node, nestedInSavedEl) {
  743. var id = node.id;
  744. // If the node has an ID then save it off since we will want
  745. // to reuse it in case the target DOM tree has a DOM element
  746. // with the same ID
  747. if (id) {
  748. savedEls[id] = node;
  749. } else if (!nestedInSavedEl) {
  750. // If we are not nested in a saved element then we know that this node has been
  751. // completely discarded and will not exist in the final DOM.
  752. onNodeDiscarded(node);
  753. }
  754. if (node.nodeType === 1) {
  755. var curChild = node.firstChild;
  756. while(curChild) {
  757. removeNodeHelper(curChild, nestedInSavedEl || id);
  758. curChild = curChild.nextSibling;
  759. }
  760. }
  761. }
  762. function walkDiscardedChildNodes(node) {
  763. if (node.nodeType === 1) {
  764. var curChild = node.firstChild;
  765. while(curChild) {
  766. if (!curChild.id) {
  767. // We only want to handle nodes that don't have an ID to avoid double
  768. // walking the same saved element.
  769. onNodeDiscarded(curChild);
  770. // Walk recursively
  771. walkDiscardedChildNodes(curChild);
  772. }
  773. curChild = curChild.nextSibling;
  774. }
  775. }
  776. }
  777. function removeNode(node, parentNode, alreadyVisited) {
  778. parentNode.removeChild(node);
  779. if (alreadyVisited) {
  780. if (!node.id) {
  781. onNodeDiscarded(node);
  782. walkDiscardedChildNodes(node);
  783. }
  784. } else {
  785. removeNodeHelper(node);
  786. }
  787. }
  788. function morphEl(fromNode, toNode, alreadyVisited) {
  789. if (toNode.id) {
  790. // If an element with an ID is being morphed then it is will be in the final
  791. // DOM so clear it out of the saved elements collection
  792. delete savedEls[toNode.id];
  793. }
  794. if (onBeforeMorphEl(fromNode, toNode) === false) {
  795. return;
  796. }
  797. morphAttrs(fromNode, toNode);
  798. if (onBeforeMorphElChildren(fromNode, toNode) === false) {
  799. return;
  800. }
  801. var curToNodeChild = toNode.firstChild;
  802. var curFromNodeChild = fromNode.firstChild;
  803. var curToNodeId;
  804. var fromNextSibling;
  805. var toNextSibling;
  806. var savedEl;
  807. var unmatchedEl;
  808. outer: while(curToNodeChild) {
  809. toNextSibling = curToNodeChild.nextSibling;
  810. curToNodeId = curToNodeChild.id;
  811. while(curFromNodeChild) {
  812. var curFromNodeId = curFromNodeChild.id;
  813. fromNextSibling = curFromNodeChild.nextSibling;
  814. if (!alreadyVisited) {
  815. if (curFromNodeId && (unmatchedEl = unmatchedEls[curFromNodeId])) {
  816. unmatchedEl.parentNode.replaceChild(curFromNodeChild, unmatchedEl);
  817. morphEl(curFromNodeChild, unmatchedEl, alreadyVisited);
  818. curFromNodeChild = fromNextSibling;
  819. continue;
  820. }
  821. }
  822. var curFromNodeType = curFromNodeChild.nodeType;
  823. if (curFromNodeType === curToNodeChild.nodeType) {
  824. var isCompatible = false;
  825. if (curFromNodeType === 1) { // Both nodes being compared are Element nodes
  826. if (curFromNodeChild.tagName === curToNodeChild.tagName) {
  827. // We have compatible DOM elements
  828. if (curFromNodeId || curToNodeId) {
  829. // If either DOM element has an ID then we handle
  830. // those differently since we want to match up
  831. // by ID
  832. if (curToNodeId === curFromNodeId) {
  833. isCompatible = true;
  834. }
  835. } else {
  836. isCompatible = true;
  837. }
  838. }
  839. if (isCompatible) {
  840. // We found compatible DOM elements so add a
  841. // task to morph the compatible DOM elements
  842. morphEl(curFromNodeChild, curToNodeChild, alreadyVisited);
  843. }
  844. } else if (curFromNodeType === 3) { // Both nodes being compared are Text nodes
  845. isCompatible = true;
  846. curFromNodeChild.nodeValue = curToNodeChild.nodeValue;
  847. }
  848. if (isCompatible) {
  849. curToNodeChild = toNextSibling;
  850. curFromNodeChild = fromNextSibling;
  851. continue outer;
  852. }
  853. }
  854. // No compatible match so remove the old node from the DOM
  855. removeNode(curFromNodeChild, fromNode, alreadyVisited);
  856. curFromNodeChild = fromNextSibling;
  857. }
  858. if (curToNodeId) {
  859. if ((savedEl = savedEls[curToNodeId])) {
  860. morphEl(savedEl, curToNodeChild, true);
  861. curToNodeChild = savedEl; // We want to append the saved element instead
  862. } else {
  863. // The current DOM element in the target tree has an ID
  864. // but we did not find a match in any of the corresponding
  865. // siblings. We just put the target element in the old DOM tree
  866. // but if we later find an element in the old DOM tree that has
  867. // a matching ID then we will replace the target element
  868. // with the corresponding old element and morph the old element
  869. unmatchedEls[curToNodeId] = curToNodeChild;
  870. }
  871. }
  872. // If we got this far then we did not find a candidate match for our "to node"
  873. // and we exhausted all of the children "from" nodes. Therefore, we will just
  874. // append the current "to node" to the end
  875. fromNode.appendChild(curToNodeChild);
  876. curToNodeChild = toNextSibling;
  877. curFromNodeChild = fromNextSibling;
  878. }
  879. // We have processed all of the "to nodes". If curFromNodeChild is non-null then
  880. // we still have some from nodes left over that need to be removed
  881. while(curFromNodeChild) {
  882. fromNextSibling = curFromNodeChild.nextSibling;
  883. removeNode(curFromNodeChild, fromNode, alreadyVisited);
  884. curFromNodeChild = fromNextSibling;
  885. }
  886. var specialElHandler = specialElHandlers[fromNode.tagName];
  887. if (specialElHandler) {
  888. specialElHandler(fromNode, toNode);
  889. }
  890. }
  891. var morphedNode = fromNode;
  892. var morphedNodeType = morphedNode.nodeType;
  893. var toNodeType = toNode.nodeType;
  894. // Handle the case where we are given two DOM nodes that are not
  895. // compatible (e.g. <div> --> <span> or <div> --> TEXT)
  896. if (morphedNodeType === 1) {
  897. if (toNodeType === 1) {
  898. if (morphedNode.tagName !== toNode.tagName) {
  899. onNodeDiscarded(fromNode);
  900. morphedNode = moveChildren(morphedNode, document.createElement(toNode.tagName));
  901. }
  902. } else {
  903. // Going from an element node to a text node
  904. return toNode;
  905. }
  906. } else if (morphedNodeType === 3) { // Text node
  907. if (toNodeType === 3) {
  908. morphedNode.nodeValue = toNode.nodeValue;
  909. return morphedNode;
  910. } else {
  911. onNodeDiscarded(fromNode);
  912. // Text node to something else
  913. return toNode;
  914. }
  915. }
  916. morphEl(morphedNode, toNode, false);
  917. // Fire the "onNodeDiscarded" event for any saved elements
  918. // that never found a new home in the morphed DOM
  919. for (var savedElId in savedEls) {
  920. if (savedEls.hasOwnProperty(savedElId)) {
  921. var savedEl = savedEls[savedElId];
  922. onNodeDiscarded(savedEl);
  923. walkDiscardedChildNodes(savedEl);
  924. }
  925. }
  926. if (morphedNode !== fromNode && fromNode.parentNode) {
  927. fromNode.parentNode.replaceChild(morphedNode, fromNode);
  928. }
  929. return morphedNode;
  930. }
  931. module.exports = morphdom;
  932. },{}]},{},[1])(1)
  933. });