popup.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. (function() {
  2. var customProfiles, i, module, moveDown, moveUp, shortcutKeys, _i,
  3. __hasProp = {}.hasOwnProperty;
  4. module = angular.module('omegaPopup', ['omegaTarget', 'omegaDecoration', 'ui.bootstrap', 'ui.validate']);
  5. module.filter('tr', function(omegaTarget) {
  6. return omegaTarget.getMessage;
  7. });
  8. module.filter('dispName', function(omegaTarget) {
  9. return function(name) {
  10. if (typeof name === 'object') {
  11. name = name.name;
  12. }
  13. return omegaTarget.getMessage('profile_' + name) || name;
  14. };
  15. });
  16. moveUp = function(activeIndex, items) {
  17. var i, _ref;
  18. i = activeIndex - 1;
  19. if (i >= 0) {
  20. return (_ref = items.eq(i)[0]) != null ? _ref.focus() : void 0;
  21. }
  22. };
  23. moveDown = function(activeIndex, items) {
  24. var _ref;
  25. return (_ref = items.eq(activeIndex + 1)[0]) != null ? _ref.focus() : void 0;
  26. };
  27. shortcutKeys = {
  28. 38: moveUp,
  29. 40: moveDown,
  30. 74: moveDown,
  31. 75: moveUp,
  32. 48: '+direct',
  33. 83: '+system',
  34. 191: 'help',
  35. 63: 'help',
  36. 69: 'external',
  37. 65: 'addRule',
  38. 43: 'addRule',
  39. 61: 'addRule',
  40. 84: 'tempRule',
  41. 79: 'option',
  42. 82: 'requestInfo'
  43. };
  44. for (i = _i = 1; _i <= 9; i = ++_i) {
  45. shortcutKeys[48 + i] = i;
  46. }
  47. customProfiles = (function() {
  48. var _customProfiles;
  49. _customProfiles = null;
  50. return function() {
  51. return _customProfiles != null ? _customProfiles : _customProfiles = jQuery('.custom-profile:not(.ng-hide) > a');
  52. };
  53. })();
  54. jQuery(document).on('keydown', function(e) {
  55. var handler, items, key, keys, shortcut, showHelp, _ref, _ref1;
  56. handler = shortcutKeys[e.keyCode];
  57. if (!handler) {
  58. return;
  59. }
  60. if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
  61. return;
  62. }
  63. switch (typeof handler) {
  64. case 'string':
  65. switch (handler) {
  66. case 'help':
  67. showHelp = function(element, key) {
  68. var span;
  69. if (typeof element === 'string') {
  70. element = jQuery("a[data-shortcut='" + element + "']");
  71. }
  72. span = jQuery('.shortcut-help', element);
  73. if (span.length === 0) {
  74. span = jQuery('<span/>').addClass('shortcut-help');
  75. }
  76. span.text(key);
  77. return element.find('.glyphicon').after(span);
  78. };
  79. keys = {
  80. '+direct': '0',
  81. '+system': 'S',
  82. 'external': 'E',
  83. 'addRule': 'A',
  84. 'tempRule': 'T',
  85. 'option': 'O',
  86. 'requestInfo': 'R'
  87. };
  88. for (shortcut in keys) {
  89. key = keys[shortcut];
  90. showHelp(shortcut, key);
  91. }
  92. customProfiles().each(function(i, el) {
  93. if (i <= 8) {
  94. return showHelp(jQuery(el), i + 1);
  95. }
  96. });
  97. break;
  98. default:
  99. if ((_ref = jQuery("a[data-shortcut='" + handler + "']")[0]) != null) {
  100. _ref.click();
  101. }
  102. }
  103. break;
  104. case 'number':
  105. if ((_ref1 = customProfiles().eq(handler - 1)) != null) {
  106. _ref1.click();
  107. }
  108. break;
  109. case 'function':
  110. items = jQuery('.popup-menu-nav > li:not(.ng-hide) > a');
  111. i = items.index(jQuery(e.target).closest('a'));
  112. if (i === -1) {
  113. i = items.index(jQuery('.popup-menu-nav > li.active > a'));
  114. }
  115. handler(i, items);
  116. }
  117. return false;
  118. });
  119. module.controller('PopupCtrl', function($scope, $window, $q, omegaTarget, profileIcons, profileOrder, dispNameFilter, getVirtualTarget) {
  120. var preselectedProfileNameForCondition, refresh, refreshOnProfileChange;
  121. $scope.closePopup = function() {
  122. return $window.close();
  123. };
  124. $scope.openManage = function() {
  125. omegaTarget.openManage();
  126. return $window.close();
  127. };
  128. refreshOnProfileChange = false;
  129. refresh = function() {
  130. if (refreshOnProfileChange) {
  131. return omegaTarget.refreshActivePage().then(function() {
  132. return $window.close();
  133. });
  134. } else {
  135. return $window.close();
  136. }
  137. };
  138. $scope.profileIcons = profileIcons;
  139. $scope.dispNameFilter = dispNameFilter;
  140. $scope.isActive = function(profileName) {
  141. if ($scope.isSystemProfile) {
  142. return profileName === 'system';
  143. } else {
  144. return $scope.currentProfileName === profileName;
  145. }
  146. };
  147. $scope.isEffective = function(profileName) {
  148. return $scope.isSystemProfile && $scope.currentProfileName === profileName;
  149. };
  150. $scope.getIcon = function(profile, normal) {
  151. if (!profile) {
  152. return;
  153. }
  154. if (!normal && $scope.isEffective(profile.name)) {
  155. return 'glyphicon-ok';
  156. } else {
  157. return void 0;
  158. }
  159. };
  160. $scope.getProfileTitle = function(profile, normal) {
  161. var desc;
  162. desc = '';
  163. while (profile) {
  164. desc = profile.desc;
  165. profile = getVirtualTarget(profile, $scope.availableProfiles);
  166. }
  167. return desc || (profile != null ? profile.name : void 0) || '';
  168. };
  169. $scope.openOptions = function(hash) {
  170. return omegaTarget.openOptions(hash).then(function() {
  171. return $window.close();
  172. });
  173. };
  174. $scope.openConditionHelp = function() {
  175. var pname;
  176. pname = encodeURIComponent($scope.currentProfileName);
  177. return $scope.openOptions("#/profile/" + pname + "?help=condition");
  178. };
  179. $scope.applyProfile = function(profile) {
  180. var apply, next;
  181. next = function() {
  182. if (profile.profileType === 'SwitchProfile') {
  183. return omegaTarget.state('web.switchGuide').then(function(switchGuide) {
  184. if (switchGuide === 'showOnFirstUse') {
  185. return $scope.openOptions("#/profile/" + profile.name);
  186. }
  187. });
  188. }
  189. };
  190. if (!refreshOnProfileChange) {
  191. omegaTarget.applyProfileNoReply(profile.name);
  192. apply = next();
  193. } else {
  194. apply = omegaTarget.applyProfile(profile.name).then(function() {
  195. return omegaTarget.refreshActivePage();
  196. }).then(next);
  197. }
  198. if (apply) {
  199. return apply.then(function() {
  200. return $window.close();
  201. });
  202. } else {
  203. return $window.close();
  204. }
  205. };
  206. $scope.tempRuleMenu = {
  207. open: false
  208. };
  209. $scope.nameExternal = {
  210. open: false
  211. };
  212. $scope.addTempRule = function(domain, profileName) {
  213. $scope.tempRuleMenu.open = false;
  214. return omegaTarget.addTempRule(domain, profileName).then(function() {
  215. omegaTarget.state('lastProfileNameForCondition', profileName);
  216. return refresh();
  217. });
  218. };
  219. $scope.setDefaultProfile = function(profileName, defaultProfileName) {
  220. return omegaTarget.setDefaultProfile(profileName, defaultProfileName).then(function() {
  221. return refresh();
  222. });
  223. };
  224. $scope.addCondition = function(condition, profileName) {
  225. return omegaTarget.addCondition(condition, profileName).then(function() {
  226. omegaTarget.state('lastProfileNameForCondition', profileName);
  227. return refresh();
  228. });
  229. };
  230. $scope.addConditionForDomains = function(domains, profileName) {
  231. var conditions, domain, enabled;
  232. conditions = [];
  233. for (domain in domains) {
  234. if (!__hasProp.call(domains, domain)) continue;
  235. enabled = domains[domain];
  236. if (enabled) {
  237. conditions.push({
  238. conditionType: 'HostWildcardCondition',
  239. pattern: domain
  240. });
  241. }
  242. }
  243. return omegaTarget.addCondition(conditions, profileName).then(function() {
  244. omegaTarget.state('lastProfileNameForCondition', profileName);
  245. return refresh();
  246. });
  247. };
  248. $scope.validateProfileName = {
  249. conflict: '!$value || !availableProfiles["+" + $value]',
  250. hidden: '!$value || $value[0] != "_"'
  251. };
  252. $scope.saveExternal = function() {
  253. var name;
  254. $scope.nameExternal.open = false;
  255. name = $scope.externalProfile.name;
  256. if (name) {
  257. return omegaTarget.addProfile($scope.externalProfile).then(function() {
  258. return omegaTarget.applyProfile(name).then(function() {
  259. return refresh();
  260. });
  261. });
  262. }
  263. };
  264. $scope.returnToMenu = function() {
  265. if (location.hash.indexOf('!') >= 0) {
  266. location.href = 'popup/index.html';
  267. return;
  268. }
  269. $scope.showConditionForm = false;
  270. return $scope.showRequestInfo = false;
  271. };
  272. preselectedProfileNameForCondition = 'direct';
  273. if ($window.location.hash === '#!requestInfo') {
  274. $scope.showRequestInfo = true;
  275. } else if ($window.location.hash === '#!external') {
  276. $scope.nameExternal = {
  277. open: true
  278. };
  279. }
  280. omegaTarget.state(['availableProfiles', 'currentProfileName', 'isSystemProfile', 'validResultProfiles', 'refreshOnProfileChange', 'externalProfile', 'proxyNotControllable', 'lastProfileNameForCondition']).then(function(_arg) {
  281. var availableProfiles, charCodeUnderscore, currentProfileName, externalProfile, isSystemProfile, key, lastProfileNameForCondition, profile, profilesByNames, proxyNotControllable, refresh, validResultProfiles, _j, _len, _ref;
  282. availableProfiles = _arg[0], currentProfileName = _arg[1], isSystemProfile = _arg[2], validResultProfiles = _arg[3], refresh = _arg[4], externalProfile = _arg[5], proxyNotControllable = _arg[6], lastProfileNameForCondition = _arg[7];
  283. $scope.proxyNotControllable = proxyNotControllable;
  284. if (proxyNotControllable) {
  285. return;
  286. }
  287. $scope.availableProfiles = availableProfiles;
  288. $scope.currentProfile = availableProfiles['+' + currentProfileName];
  289. $scope.currentProfileName = currentProfileName;
  290. $scope.isSystemProfile = isSystemProfile;
  291. $scope.externalProfile = externalProfile;
  292. refreshOnProfileChange = refresh;
  293. charCodeUnderscore = '_'.charCodeAt(0);
  294. profilesByNames = function(names) {
  295. var name, profiles, shown, _j, _len;
  296. profiles = [];
  297. for (_j = 0, _len = names.length; _j < _len; _j++) {
  298. name = names[_j];
  299. shown = name.charCodeAt(0) !== charCodeUnderscore || name.charCodeAt(1) !== charCodeUnderscore;
  300. if (shown) {
  301. profiles.push(availableProfiles['+' + name]);
  302. }
  303. }
  304. return profiles;
  305. };
  306. $scope.validResultProfiles = profilesByNames(validResultProfiles);
  307. if (lastProfileNameForCondition) {
  308. _ref = $scope.validResultProfiles;
  309. for (_j = 0, _len = _ref.length; _j < _len; _j++) {
  310. profile = _ref[_j];
  311. if (profile.name === lastProfileNameForCondition) {
  312. preselectedProfileNameForCondition = lastProfileNameForCondition;
  313. }
  314. }
  315. }
  316. $scope.builtinProfiles = [];
  317. $scope.customProfiles = [];
  318. for (key in availableProfiles) {
  319. if (!__hasProp.call(availableProfiles, key)) continue;
  320. profile = availableProfiles[key];
  321. if (profile.builtin) {
  322. $scope.builtinProfiles.push(profile);
  323. } else if (profile.name.charCodeAt(0) !== charCodeUnderscore) {
  324. $scope.customProfiles.push(profile);
  325. }
  326. if (profile.validResultProfiles) {
  327. profile.validResultProfiles = profilesByNames(profile.validResultProfiles);
  328. }
  329. }
  330. return $scope.customProfiles.sort(profileOrder);
  331. });
  332. $scope.domainsForCondition = {};
  333. $scope.requestInfoProvided = null;
  334. omegaTarget.setRequestInfoCallback(function(info) {
  335. var domain, domainInfo, _ref;
  336. info.domains = [];
  337. _ref = info.summary;
  338. for (domain in _ref) {
  339. if (!__hasProp.call(_ref, domain)) continue;
  340. domainInfo = _ref[domain];
  341. domainInfo.domain = domain;
  342. info.domains.push(domainInfo);
  343. }
  344. info.domains.sort(function(a, b) {
  345. return b.errorCount - a.errorCount;
  346. });
  347. return $scope.$apply(function() {
  348. var _base, _j, _len, _name, _ref1;
  349. $scope.requestInfo = info;
  350. if ($scope.requestInfoProvided == null) {
  351. $scope.requestInfoProvided = (info != null ? info.domains.length : void 0) > 0;
  352. }
  353. _ref1 = info.domains;
  354. for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
  355. domain = _ref1[_j];
  356. if ((_base = $scope.domainsForCondition)[_name = domain.domain] == null) {
  357. _base[_name] = true;
  358. }
  359. }
  360. return $scope.profileForDomains != null ? $scope.profileForDomains : $scope.profileForDomains = preselectedProfileNameForCondition;
  361. });
  362. });
  363. $q.all([omegaTarget.state('currentProfileCanAddRule'), omegaTarget.getActivePageInfo()]).then(function(_arg) {
  364. var canAddRule, info;
  365. canAddRule = _arg[0], info = _arg[1];
  366. $scope.currentProfileCanAddRule = canAddRule;
  367. if (info) {
  368. $scope.currentTempRuleProfile = info.tempRuleProfileName;
  369. if ($scope.currentTempRuleProfile) {
  370. preselectedProfileNameForCondition = $scope.currentTempRuleProfile;
  371. }
  372. $scope.currentDomain = info.domain;
  373. if ($window.location.hash === '#!addRule') {
  374. return $scope.prepareConditionForm();
  375. }
  376. }
  377. });
  378. return $scope.prepareConditionForm = function() {
  379. var conditionSuggestion, currentDomain, currentDomainEscaped, domainLooksLikeIp;
  380. currentDomain = $scope.currentDomain;
  381. currentDomainEscaped = currentDomain.replace(/\./g, '\\.');
  382. domainLooksLikeIp = false;
  383. if (currentDomain.indexOf(':') >= 0) {
  384. domainLooksLikeIp = true;
  385. if (currentDomain[0] !== '[') {
  386. currentDomain = '[' + currentDomain + ']';
  387. currentDomainEscaped = currentDomain.replace(/\./g, '\\.').replace(/\[/g, '\\[').replace(/\]/g, '\\]');
  388. }
  389. } else if (currentDomain[currentDomain.length - 1] >= 0) {
  390. domainLooksLikeIp = true;
  391. }
  392. if (domainLooksLikeIp) {
  393. conditionSuggestion = {
  394. 'HostWildcardCondition': currentDomain,
  395. 'HostRegexCondition': '^' + currentDomainEscaped + '$',
  396. 'UrlWildcardCondition': '*://' + currentDomain + '/*',
  397. 'UrlRegexCondition': '://' + currentDomainEscaped + '(:\\d+)?/',
  398. 'KeywordCondition': currentDomain
  399. };
  400. } else {
  401. conditionSuggestion = {
  402. 'HostWildcardCondition': '*.' + currentDomain,
  403. 'HostRegexCondition': '(^|\\.)' + currentDomainEscaped + '$',
  404. 'UrlWildcardCondition': '*://*.' + currentDomain + '/*',
  405. 'UrlRegexCondition': '://([^/.]+\\.)*' + currentDomainEscaped + '(:\\d+)?/',
  406. 'KeywordCondition': currentDomain
  407. };
  408. }
  409. $scope.rule = {
  410. condition: {
  411. conditionType: 'HostWildcardCondition',
  412. pattern: conditionSuggestion['HostWildcardCondition']
  413. },
  414. profileName: preselectedProfileNameForCondition
  415. };
  416. $scope.$watch('rule.condition.conditionType', function(type) {
  417. return $scope.rule.condition.pattern = conditionSuggestion[type];
  418. });
  419. return $scope.showConditionForm = true;
  420. };
  421. });
  422. }).call(this);