jHueTourBuilder.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. $("<style type='text/css'> .tooltip {z-index: 30000} .tourBuilder td { vertical-align: text-top } .tourBuilder span[rel='tooltip'] {cursor: pointer; color: #FFF; font-size: 14px} .tourBuilder { overflow-y: auto; overflow-x: hidden; color: #FFF; font-size: 11px; background-color: #333; padding: 10px; opacity: 0.9; position: fixed; width: 360px; right: 0; top: 0; z-index: 15000 } .tourBuilder select, .tourBuilder textarea { font-size: 11px; } .tourBuilder input { font-size: 11px; height: 14px } </style>").appendTo($("head"));
  2. var _tbTour = {
  3. name: "",
  4. desc: "",
  5. path: location.pathname,
  6. steps: []
  7. };
  8. var _origTbTour = _tbTour;
  9. var _tb = $("<div>");
  10. _tb.addClass("tourBuilder");
  11. _tb.height($(window).height());
  12. _tb.appendTo($("body"));
  13. var _tbCog = $("<div>").attr("id", "tbCog").html('<i class="fa fa-cogs"></i>').addClass("jHueTourBadge").css("top", "64px");
  14. _tbCog.on("click", function () {
  15. _tb.show();
  16. });
  17. _tbCog.appendTo($("body"));
  18. var _html = "<h4>General</h4>" +
  19. "<table><tr><td>ID:</td><td><input class='input' type='text' id='tbName' /> <span rel='tooltip' title='unique tour name (location.pathname scope)'><i class='fa fa-question-circle'></i></span></td></tr>" +
  20. "<tr><td>Name:</td><td><input class='input' type='text' id='tbDesc' /> <span rel='tooltip' title='the label shown on the question mark'><i class='fa fa-question-circle'></i></span></td></tr>" +
  21. "<tr><td>Path:</td><td><input class='input' type='text' id='tbPath' value='" + _tbTour.path + "'/> <span rel='tooltip' title='string for the path to show this tour on, regex allowed'><i class='fa fa-question-circle'></i></span></td></tr></table>" +
  22. "<h4>New step</h4><table>" +
  23. "<tr><td>Visit URL:</td><td><input class='input' type='text' id='tbNewURL' /> <span rel='tooltip' title='overrides everything, redirects to specific url'><i class='fa fa-question-circle'></i></span></td></tr>" +
  24. "<tr><td colspan='2'>&nbsp;</td></tr>" +
  25. "<tr><td>Arrow on:</td><td><input class='input' type='text' id='tbNewArrow' /> <span rel='tooltip' title='the element relative to the popover is positioned'><i class='fa fa-question-circle'></i></span></td></tr>" +
  26. "<tr><td>Expose:</td><td><input class='input' type='text' id='tbNewExpose' /> <span rel='tooltip' title='optional, the exposed object. if not present, arrowOn will be exposed'><i class='fa fa-question-circle'></i></span></td></tr>" +
  27. "<tr><td>Title:</td><td><input class='input' type='text' id='tbNewTitle'/> <span rel='tooltip' title='popover title'><i class='fa fa-question-circle'></i></span></td></tr>" +
  28. "<tr><td>Content:</td><td><textarea id='tbNewContent'></textarea> <span rel='tooltip' title='popover content, html enabled'><i class='fa fa-question-circle'></i></span></td></tr>" +
  29. "<tr><td>Placement:</td><td><select class='input' id='tbNewPlacement'><option value='top' selected='selected'>Top</option><option value='bottom'>Bottom</option><option value='left'>Left</option><option value='right'>Right</option> </select> <span rel='tooltip' title='popover placement'><i class='fa fa-question-circle'></i></span></td></tr>" +
  30. "<tr><td>Left:</td><td>Offset <input type='text' class='input-mini' id='tbNewOffsetLeft'/> Abs <input type='text' class='input-mini' id='tbNewAbsLeft'/></td></tr>" +
  31. "<tr><td>Top:</td><td>Offset <input type='text' class='input-mini' id='tbNewOffsetTop'/> Abs <input type='text' class='input-mini' id='tbNewAbsTop'/></td></tr>" +
  32. "<tr><td>On shown:</td><td><textarea id='tbNewShown'></textarea> <span rel='tooltip' title='javascript run on popover step shown. DANGER!'><i class='fa fa-question-circle'></i></span></td></tr>" +
  33. "<tr><td>Wait:</td><td><input type='checkbox' id='tbNewWait'/> <span rel='tooltip' title='does not show the next button and waits for an action to go on with the tour'><i class='fa fa-question-circle'></i></span></td></tr>" +
  34. "<tr><td>&nbsp;</td><td style='text-align: right'><a href='javascript:void(0)' id='tbNewShow' class='btn btn-mini'>Show</a> <a id='tbNewAdd' href='javascript:void(0)' class='btn btn-mini'>Add to tour</a> </td></tr>" +
  35. "</table><h4>Steps</h4>" +
  36. "<div id='tbSteps'></div>" +
  37. "<h4>JSON</h4>" +
  38. "<textarea id='tbPreview' style='width: 90%'>" + JSON.stringify(_tbTour) + "</textarea><br/><a href='javascript:void(0)' id='tbLoadJson' class='btn btn-mini'>Load from JSON</a><br/><br/>" +
  39. "<div style='text-align: right'><a id='tbManageTours' class='btn' href='javascript:void(0)' style='float:left'><i class='fa fa-sitemap'></i></a> <a id='tbAddTour' class='btn' href='javascript:void(0)'><i class='fa fa-plus-circle-alt'></i></a> <a id='tbClearCache' class='btn' href='javascript:void(0)'><i class='fa fa-trash-o'></i></a> <a id='tbTryTour' title='Try tour' class='btn' href='javascript:void(0)'><i class='fa fa-eye'></i></a></div><br/><br/>";
  40. _tb.html(_html);
  41. var _managerHtml = "<div id='tbToursModal' class='modal hide fade'>" +
  42. "<div class='modal-header'>" +
  43. "<button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>" +
  44. "<h3>Available tours</h3>" +
  45. "</div>" +
  46. "<div class='modal-body'>" +
  47. "<p><span id='tbTourList'></span><br/><h4>Content for tours.mako</h4><textarea id='tbAvailableContent' style='width:90%'></textarea><br/><a href='javascript:void(0)' id='tbLoadToursJson' class='btn btn-mini'>Load from JSON</a></p>" +
  48. "</div>" +
  49. "<div class='modal-footer'><a href='javascript:void(0)' data-dismiss='modal' class='btn'>Close</a></div></div>";
  50. $(_managerHtml).appendTo($("body"));
  51. $("span[rel='tooltip']").tooltip({
  52. placement: "left"
  53. });
  54. _tb.find("input").on("change", function () {
  55. updateTour();
  56. });
  57. $("textarea").on("focus", function () {
  58. var $this = $(this);
  59. $this.select();
  60. // Work around Chrome's little problem
  61. $this.mouseup(function () {
  62. // Prevent further mouseup intervention
  63. $this.unbind("mouseup");
  64. return false;
  65. });
  66. });
  67. var _tbTourIsEditing = -1;
  68. var _tbTourIsStepEditing = -1;
  69. function updateTour() {
  70. _tbTour.name = $("#tbName").val();
  71. _tbTour.desc = $("#tbDesc").val();
  72. _tbTour.path = $("#tbPath").val();
  73. if ($("#tbNewExpose").val() == "") {
  74. $("#tbNewExpose").val($("#tbNewArrow").val());
  75. }
  76. function fillItem(item) {
  77. $("#tbNewURL").val(item.visitUrl);
  78. $("#tbNewArrow").val(item.arrowOn);
  79. $("#tbNewExpose").val(item.expose);
  80. $("#tbNewTitle").val(item.title);
  81. $("#tbNewContent").val(item.content);
  82. $("#tbNewPlacement").val(item.placement);
  83. $("#tbNewShown").val(item.onShown);
  84. if (item.waitForAction == true){
  85. $("#tbNewWait").prop("checked", true);
  86. }
  87. else {
  88. $("#tbNewWait").prop("checked", false);
  89. }
  90. $("#tbNewOffsetTop").val("");
  91. $("#tbNewAbsTop").val("");
  92. $("#tbNewOffsetLeft").val("");
  93. $("#tbNewAbsLeft").val("");
  94. if (item.left != undefined && item.left != "") {
  95. if ($.isNumeric(item.left)) {
  96. $("#tbNewOffsetLeft").val(item.left);
  97. }
  98. else {
  99. $("#tbNewAbsLeft").val(item.left.substring(0, item.left.length - 2));
  100. }
  101. }
  102. if (item.top != undefined && item.top != "") {
  103. if ($.isNumeric(item.top)) {
  104. $("#tbNewOffsetTop").val(item.top);
  105. }
  106. else {
  107. $("#tbNewAbsTop").val(item.top.substring(0, item.top.length - 2));
  108. }
  109. }
  110. }
  111. $("#tbSteps").empty();
  112. $(_tbTour.steps).each(function (cnt, item) {
  113. var _trow = $("<div>").html("&nbsp;" + (item.visitUrl!="" && item.visitUrl!=undefined?"URL: " + item.visitUrl:"Title: "+item.title));
  114. var _trowdelete = $("<a>");
  115. _trowdelete.addClass("btn").addClass("btn-mini").html("<i class='fa fa-trash-o'></i>").css("margin", "3px").on("click", function () {
  116. _tbTour.steps.splice(cnt, 1);
  117. updateTour();
  118. });
  119. _trowdelete.prependTo(_trow);
  120. var _trowcopy = $("<a>");
  121. _trowcopy.addClass("btn").addClass("btn-mini").html("<i class='fa fa-files-o'></i>").css("margin", "3px").on("click", function () {
  122. fillItem(item);
  123. });
  124. _trowcopy.prependTo(_trow);
  125. var _trowedit = $("<a>");
  126. _trowedit.addClass("btn").addClass("btn-mini").html("<i class='fa fa-edit'></i>").css("margin", "3px").on("click", function () {
  127. fillItem(item);
  128. _tbTourIsStepEditing = cnt;
  129. $("#tbNewAdd").text("Update step");
  130. });
  131. _trowedit.prependTo(_trow);
  132. var _trowup = $("<a>");
  133. _trowup.addClass("btn").addClass("btn-mini").html("<i class='fa fa-arrow-up'></i>").css("margin", "3px").on("click", function () {
  134. var _newPos = cnt - 1;
  135. if (cnt == 0) {
  136. _newPos = _tbTour.steps.length - 1;
  137. }
  138. _tbTour.steps.move(cnt, _newPos);
  139. updateTour();
  140. });
  141. _trowup.prependTo(_trow);
  142. var _trowdown = $("<a>");
  143. _trowdown.addClass("btn").addClass("btn-mini").html("<i class='fa fa-arrow-down'></i>").css("margin", "3px").on("click", function () {
  144. var _newPos = cnt + 1;
  145. if (cnt == _tbTour.steps.length - 1) {
  146. _newPos = 0;
  147. }
  148. _tbTour.steps.move(cnt, _newPos);
  149. updateTour();
  150. });
  151. _trowdown.prependTo(_trow);
  152. _trow.appendTo($("#tbSteps"));
  153. });
  154. $("#tbPreview").val(JSON.stringify(_tbTour));
  155. $.totalStorage("jHueTourBuilderTemp", _tbTour);
  156. }
  157. $("#tbLoadJson").on("click", function () {
  158. _tbTourIsStepEditing = -1;
  159. try {
  160. _tbTour = JSON.parse($.trim($("#tbPreview").val()));
  161. $("#tbName").val(_tbTour.name);
  162. $("#tbDesc").val(_tbTour.desc);
  163. $("#tbPath").val(_tbTour.path);
  164. updateTour();
  165. }
  166. catch (exception) {
  167. alert("It seems you don't eat JSON for breakfast:" + exception)
  168. }
  169. });
  170. $("#tbLoadToursJson").on("click", function () {
  171. _tbTourIsEditing = -1;
  172. _tbTourIsStepEditing = -1;
  173. try {
  174. var _paste = $.trim($("#tbAvailableContent").val());
  175. if (_paste.indexOf("$.jHueTour") > -1){
  176. _paste = _paste.substr(11);
  177. }
  178. if (_paste[_paste.length - 1] == ";"){
  179. _paste = _paste.substring(0, _paste.length - 2);
  180. }
  181. var _trz = JSON.parse(_paste);
  182. $.totalStorage("jHueTourBuilderTours", _trz.tours);
  183. $("#tbManageTours").click();
  184. }
  185. catch (exception) {
  186. alert("It seems you don't eat JSON for breakfast:" + exception)
  187. }
  188. });
  189. $("#tbNewShow").on("click", function () {
  190. $(".popover").remove();
  191. _tbTourIsEditing = -1;
  192. _tbTourIsStepEditing = -1;
  193. $(".jHueTourExposed").removeClass("jHueTourExposed").css("position", "");
  194. $("#jHueTourMask").width($(document).width()).height($(document).height()).show();
  195. var _closeBtn = $("<a>");
  196. _closeBtn.addClass("btn").addClass("btn-mini").html('<i class="fa fa-times"></i>').css("float", "right").css("margin-top", "-4px").css("margin-right", "-6px");
  197. _closeBtn.click(function () {
  198. $(".popover").remove();
  199. $(".jHueTourExposed").removeClass("jHueTourExposed");
  200. $("#jHueTourMask").hide();
  201. });
  202. if ($($("#tbNewArrow").val()).length > 0) {
  203. $($("#tbNewArrow").val()).popover('destroy').popover({
  204. title: $("#tbNewTitle").val(),
  205. content: $("#tbNewContent").val() + "<br/>",
  206. html: true,
  207. trigger: 'manual',
  208. placement: $("#tbNewPlacement").val()
  209. }).popover('show');
  210. if ($("#tbNewOffsetTop").val() != "") {
  211. $(".popover").css("top", ($(".popover").position().top + ($("#tbNewOffsetTop").val() * 1)) + "px");
  212. }
  213. if ($("#tbNewAbsTop").val() != "") {
  214. $(".popover").css("top", $("#tbNewAbsTop").val() + "px");
  215. }
  216. if ($("#tbNewOffsetLeft").val() != "") {
  217. $(".popover").css("left", ($(".popover").position().left + ($("#tbNewOffsetLeft").val() * 1)) + "px");
  218. }
  219. if ($("#tbNewAbsLeft").val() != "") {
  220. $(".popover").css("left", $("#tbNewAbsLeft").val() + "px");
  221. }
  222. $(".popover-title").html($("#tbNewTitle").val());
  223. _closeBtn.prependTo($(".popover-title"));
  224. $("<a class='btn btn-mini' style='margin-top:10px' onclick='alert(\"Nothing else to do? :)\")'><i class='fa fa-smile'></i></a>").appendTo($(".popover-content p"));
  225. }
  226. var _exposedElement = $($("#tbNewExpose").val());
  227. if (_exposedElement.css("position") === undefined || _exposedElement.css("position") != "fixed") {
  228. _exposedElement.css("position", "relative");
  229. }
  230. _exposedElement.addClass("jHueTourExposed");
  231. if ($("#tbNewShown").val() != "") {
  232. window.setTimeout($("#tbNewShown").val(), 10);
  233. }
  234. });
  235. Array.prototype.move = function (old_index, new_index) {
  236. if (new_index >= this.length) {
  237. var k = new_index - this.length;
  238. while ((k--) + 1) {
  239. this.push(undefined);
  240. }
  241. }
  242. this.splice(new_index, 0, this.splice(old_index, 1)[0]);
  243. return this;
  244. };
  245. $("#tbNewAdd").on("click", function () {
  246. var _newStep = {
  247. arrowOn: $("#tbNewArrow").val(),
  248. expose: $("#tbNewExpose").val(),
  249. title: $("#tbNewTitle").val(),
  250. content: $("#tbNewContent").val(),
  251. placement: $("#tbNewPlacement").val(),
  252. onShown: $("#tbNewShown").val(),
  253. waitForAction: $("#tbNewWait").is(":checked")
  254. };
  255. if ($("#tbNewURL").val() != ""){
  256. _newStep = {
  257. visitUrl: $("#tbNewURL").val()
  258. }
  259. }
  260. if ($("#tbNewOffsetTop").val() != "") {
  261. _newStep.top = $("#tbNewOffsetTop").val() * 1;
  262. }
  263. if ($("#tbNewAbsTop").val() != "") {
  264. _newStep.top = $("#tbNewAbsTop").val() + "px";
  265. }
  266. if ($("#tbNewOffsetLeft").val() != "") {
  267. _newStep.left = $("#tbNewOffsetLeft").val() * 1;
  268. }
  269. if ($("#tbNewAbsLeft").val() != "") {
  270. _newStep.left = $("#tbNewAbsLeft").val() + "px";
  271. }
  272. if (_tbTourIsStepEditing > -1) {
  273. _tbTour.steps[_tbTourIsStepEditing] = _newStep;
  274. _tbTourIsStepEditing = -1;
  275. $("#tbNewAdd").text("Add to tour");
  276. }
  277. else {
  278. _tbTour.steps.push(_newStep);
  279. }
  280. updateTour();
  281. $(".popover").remove();
  282. $(".jHueTourExposed").removeClass("jHueTourExposed");
  283. $("#jHueTourMask").hide();
  284. $("#tbNewURL").val("");
  285. $("#tbNewArrow").val("");
  286. $("#tbNewExpose").val("");
  287. $("#tbNewTitle").val("");
  288. $("#tbNewContent").val("");
  289. $("#tbNewShown").val("");
  290. $("#tbNewWait").prop("checked", false);
  291. $("#tbNewPlacement").val("");
  292. $("#tbNewOffsetTop").val("");
  293. $("#tbNewAbsTop").val("");
  294. $("#tbNewOffsetLeft").val("");
  295. $("#tbNewAbsLeft").val("");
  296. });
  297. $("#tbTryTour").on("click", function () {
  298. $.jHueTour("clear");
  299. $.jHueTour({ tours: [_tbTour]});
  300. _tb.hide();
  301. $.jHueTour("play");
  302. });
  303. $("#tbClearCache").on("click", function () {
  304. $.totalStorage("jHueTourBuilderTemp", null);
  305. _tbTour = _origTbTour;
  306. $("#tbName").val(_tbTour.name);
  307. $("#tbDesc").val(_tbTour.desc);
  308. $("#tbPath").val(_tbTour.path);
  309. updateTour();
  310. });
  311. $("#tbAddTour").on("click", function () {
  312. var _tbStoredTours = [];
  313. if ($.totalStorage("jHueTourBuilderTours") != null){
  314. _tbStoredTours = $.totalStorage("jHueTourBuilderTours");
  315. }
  316. if (_tbTourIsEditing > -1) {
  317. _tbStoredTours[_tbTourIsEditing] = _tbTour;
  318. _tbTourIsEditing = -1;
  319. $("#tbAddTour").html("<i class='fa fa-plus-circle-alt'></i>");
  320. }
  321. else {
  322. _tbStoredTours.push(_tbTour);
  323. }
  324. $.totalStorage("jHueTourBuilderTours", _tbStoredTours);
  325. $("#tbClearCache").click();
  326. });
  327. $("#tbManageTours").on("click", function () {
  328. $("#tbTourList").empty();
  329. $($.totalStorage("jHueTourBuilderTours")).each(function (cnt, item) {
  330. var _trow = $("<div>").html("&nbsp;Name: " + item.name + ", Desc: "+ item.desc + ", Path: "+ item.path);
  331. var _trowdelete = $("<a>");
  332. _trowdelete.addClass("btn").addClass("btn-mini").html("<i class='fa fa-trash-o'></i>").css("margin", "3px").on("click", function () {
  333. var _tmpTrz = $.totalStorage("jHueTourBuilderTours");
  334. _tmpTrz.splice(cnt, 1);
  335. $.totalStorage("jHueTourBuilderTours", _tmpTrz);
  336. $("#tbManageTours").click();
  337. });
  338. _trowdelete.prependTo(_trow);
  339. var _trowcopy = $("<a>");
  340. _trowcopy.addClass("btn").addClass("btn-mini").html("<i class='fa-files-oopy'></i>").css("margin", "3px").on("click", function () {
  341. $.totalStorage("jHueTourBuilderTemp", null);
  342. _tbTour = item;
  343. $("#tbName").val(_tbTour.name);
  344. $("#tbDesc").val(_tbTour.desc);
  345. $("#tbPath").val(_tbTour.path);
  346. updateTour();
  347. $("#tbToursModal").modal("hide");
  348. });
  349. _trowcopy.prependTo(_trow);
  350. var _trowedit = $("<a>");
  351. _trowedit.addClass("btn").addClass("btn-mini").html("<i class='fa fa-edit'></i>").css("margin", "3px").on("click", function () {
  352. $.totalStorage("jHueTourBuilderTemp", null);
  353. _tbTour = item;
  354. $("#tbName").val(_tbTour.name);
  355. $("#tbDesc").val(_tbTour.desc);
  356. $("#tbPath").val(_tbTour.path);
  357. updateTour();
  358. _tbTourIsEditing = cnt;
  359. $("#tbAddTour").html("<i class='fa fa-floppy-o'></i>");
  360. $("#tbToursModal").modal("hide");
  361. });
  362. _trowedit.prependTo(_trow);
  363. _trow.appendTo($("#tbTourList"));
  364. });
  365. var _trz = {
  366. tours: $.totalStorage("jHueTourBuilderTours")
  367. };
  368. $("#tbAvailableContent").val("$.jHueTour(" + JSON.stringify(_trz) + ");");
  369. $("#tbToursModal").modal("show");
  370. });
  371. var _changeSide = $("<a>");
  372. _changeSide.addClass("btn").addClass("btn-mini").addClass("pull-right");
  373. _changeSide.on("click", function (e) {
  374. e.preventDefault();
  375. e.stopImmediatePropagation();
  376. if (_tb.css("left") != "0px") {
  377. _tb.css("left", "0");
  378. _tb.css("right", "auto");
  379. $(this).html("<i class='fa fa-arrow-right'></i>");
  380. }
  381. else {
  382. _tb.css("right", "0");
  383. _tb.css("left", "auto");
  384. $(this).html("<i class='fa fa-arrow-left'></i>");
  385. }
  386. });
  387. _changeSide.html("<i class='fa fa-arrow-left'></i>");
  388. _changeSide.prependTo(_tb);
  389. var _hideTb = $("<a>");
  390. _hideTb.addClass("btn").addClass("btn-mini").addClass("pull-right").css("margin-left", "4px");
  391. _hideTb.on("click", function (e) {
  392. e.preventDefault();
  393. e.stopImmediatePropagation();
  394. _tb.hide();
  395. });
  396. _hideTb.html("<i class='fa fa-times'></i>");
  397. _hideTb.prependTo(_tb);
  398. // preload
  399. if ($.totalStorage("jHueTourBuilderTemp") != null){
  400. _tbTour = $.totalStorage("jHueTourBuilderTemp");
  401. $("#tbName").val(_tbTour.name);
  402. $("#tbDesc").val(_tbTour.desc);
  403. $("#tbPath").val(_tbTour.path);
  404. updateTour();
  405. }
  406. if ($.totalStorage("jHueTourBuilderTours") == null){
  407. $.totalStorage("jHueTourBuilderTours", []);
  408. }
  409. else {
  410. $($.totalStorage("jHueTourBuilderTours")).each(function (cnt, item) {
  411. if (item.name == _tbTour.name && item.path == _tbTour.path){
  412. _tbTourIsEditing = cnt;
  413. $("#tbAddTour").html("<i class='fa fa-floppy-o'></i>");
  414. }
  415. });
  416. }
  417. $(window).resize(function () {
  418. _tb.height($(window).height());
  419. });