mark-control.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. function MarkControl(option) {
  2. this.option = option;
  3. this.maxPrefetchCount = parseInt(option.prefetchCount);
  4. this.maxPrefetchCount = this.maxPrefetchCount != undefined && this.maxPrefetchCount > 2 ? this.maxPrefetchCount : 2;
  5. this.container = option.container;
  6. this.context = {
  7. imageServer: option.imageServer,
  8. staticServer: option.staticServer,
  9. isFinish: false,
  10. prefetching: false,
  11. prefetchTask: []
  12. };
  13. // 初始化容器结构
  14. this.initContainer();
  15. // 初始化事件监听
  16. this.initTriggers(option);
  17. // 初始化功能模块
  18. this.initModules(option);
  19. //初始化评卷配置
  20. this.initSetting(option);
  21. // 初始化成功回调方法
  22. // console.log('MarkControl init success!');
  23. // if (option.success != undefined && typeof(option.success) == 'function')
  24. // {
  25. // option.success();
  26. // }
  27. }
  28. MarkControl.prototype.initContainer = function() {
  29. var height = this.option.height;
  30. if (height == undefined) {
  31. height = $(window).height();
  32. }
  33. this.container = getDom(this.main_row_dom, this).appendTo(this.container);
  34. if (this.option.enableSidear != false) {
  35. this.container.sidebar = getDom(this.sidebar_dom, this).appendTo(this.container);
  36. this.container.sidebar.css('max-height', height);
  37. }
  38. this.container.center = getDom(this.center_dom, this).appendTo(this.container);
  39. this.container.header = getDom(this.center_header_dom, this).appendTo(this.container.center).find('.header');
  40. if(this.option.switchCommonUrl!=undefined && this.option.switchCommonUrl.length>0){
  41. var switchButton = this.container.header.find('#switch-common-button');
  42. switchButton.attr('href', this.option.switchCommonUrl);
  43. switchButton.show();
  44. }
  45. this.container.centerContainer = getDom(this.center_content_dom, this).appendTo(this.container.center);
  46. this.container.centerContent = this.container.centerContainer.find('.image-content');
  47. this.container.centerNavbar = this.container.centerContent.find('nav');
  48. this.container.centerList = [];
  49. this.navNumber = 0;
  50. this.container.height(height);
  51. this.container.centerContent.css('height', height - this.container.header.parent().height());
  52. this.initHeaderAndAssistant();
  53. }
  54. MarkControl.prototype.initHeaderAndAssistant = function() {
  55. var self = this;
  56. this.container.header.find('#mark-user-name').html(this.option.userName);
  57. if (this.option.logoutTitle != undefined) {
  58. this.container.header.find('#logout-title').html(this.option.logoutTitle);
  59. }
  60. this.container.header.find('#logout-link').click(function() {
  61. self.trigger('logout.link.click');
  62. return true;
  63. })
  64. //评卷时间显示
  65. this.container.markTime = getDom(this.mark_clock_dom, this).appendTo(this.container);
  66. this.container.markTime.find('#mark-time').html(this.option.markTime);
  67. this.container.markTime.hide();
  68. this.container.clock = this.container.header.find("#mark-clock");
  69. this.container.clock.mouseover(this, function(event) {
  70. self.container.markTime.show();
  71. });
  72. this.container.clock.mouseout(this, function(event) {
  73. self.container.markTime.hide();
  74. })
  75. this.container.assistant = getDom(this.assistant_dom, this).appendTo(this.container);
  76. this.container.assistant.positionSet = false;
  77. this.container.assistantButton = this.container.header.find('#assistant-button');
  78. this.container.assistantButton.click(this, function(event) {
  79. if (self.container.assistant.positionSet == false) {
  80. self.container.assistant.offset({
  81. top: self.container.assistantButton.position().top + self.container.assistantButton.height() + 5,
  82. left: self.container.assistantButton.position().left - 85
  83. });
  84. self.container.assistant.positionSet = true;
  85. }
  86. self.container.assistant.toggle();
  87. });
  88. }
  89. MarkControl.prototype.initMarkFunction = function() {
  90. var functionList = this.container.assistant.functionList;
  91. if (functionList == undefined) {
  92. functionList = getDom(this.mark_function_dom, this).appendTo(this.container.assistant).find('#function-list');
  93. this.container.assistant.functionList = functionList;
  94. }
  95. }
  96. MarkControl.prototype.addNavGroup = function(title, content){
  97. var self = this;
  98. self.navNumber++;
  99. var nav = $('<a href="#"><span>'+title+'</span></a>').appendTo(self.container.centerNavbar);
  100. nav.attr('data-number', self.navNumber);
  101. content.attr('data-number', self.navNumber);
  102. nav.click(function(){
  103. self.container.centerNavbar.find('a').removeClass('selected');
  104. $(this).addClass('selected');
  105. for(var i in self.container.centerList){
  106. var dom = self.container.centerList[i];
  107. if(dom.attr('data-number')==$(this).attr('data-number')){
  108. dom.show();
  109. }else{
  110. dom.hide();
  111. }
  112. }
  113. });
  114. self.container.centerList.push(content);
  115. return nav;
  116. }
  117. MarkControl.prototype.initSetting = function(option) {
  118. this.userId = option.userId;
  119. this.settingSyncUrl = option.settingSyncUrl;
  120. this.settingSyncing = false;
  121. this.localStore = window.localStorage;
  122. this.setting = {};
  123. if (option.defaultSetting != undefined) {
  124. //读取外部初始化配置
  125. this.setting = JSON.parse(option.defaultSetting);
  126. } else if (this.localStore != undefined) {
  127. //读取本地存储并判断用户标识
  128. var store = JSON.parse(this.localStore.getItem('mark.setting'));
  129. if (store != undefined && store.userId != undefined && store.userId == this.userId) {
  130. this.setting = store.setting;
  131. }
  132. }
  133. //强制刷新本地存储
  134. this.localSettingSave();
  135. //广播通知所有模块初始化设置
  136. this.trigger('mark.setting.init', this.setting);
  137. }
  138. MarkControl.prototype.localSettingSave = function() {
  139. if (this.localStore != undefined) {
  140. this.localStore.setItem('mark.setting', JSON.stringify({
  141. userId: this.userId,
  142. setting: this.setting
  143. }));
  144. }
  145. }
  146. MarkControl.prototype.updateSetting = function(item) {
  147. if (item == undefined) {
  148. return;
  149. }
  150. for (var key in item) {
  151. this.setting[key] = item[key];
  152. }
  153. this.localSettingSave();
  154. if (this.settingSyncUrl != undefined && this.settingSyncing == false) {
  155. this.settingSyncing = true;
  156. var self = this;
  157. setTimeout(function() {
  158. //同步个性化设置
  159. $.post(self.settingSyncUrl, {
  160. setting: JSON.stringify(self.setting)
  161. });
  162. self.settingSyncing = false;
  163. }, 1000);
  164. }
  165. }
  166. // 增加某个事件的监听方法
  167. MarkControl.prototype.on = function(eventName, caller, callback, async) {
  168. if (eventName && callback && eventName.length > 0 && typeof(callback) == 'function') {
  169. if (async) {
  170. this.container.bind(eventName, callback);
  171. } else {
  172. if (this.triggers[eventName] == undefined) {
  173. this.triggers[eventName] = new Array();
  174. }
  175. this.triggers[eventName].push({
  176. caller: caller,
  177. callback: callback
  178. });
  179. }
  180. }
  181. }
  182. // 触发某个事件,并传递事件相关内容
  183. MarkControl.prototype.trigger = function(eventName, eventObject) {
  184. var result = true;
  185. if (eventName && eventName.length > 0) {
  186. var array = this.triggers[eventName];
  187. if (array != undefined && array.length > 0) {
  188. var event = {
  189. name: eventName
  190. }
  191. for (var i in array) {
  192. result = result & array[i].callback.call(array[i].caller, event, this.context, eventObject);
  193. }
  194. }
  195. this.container.trigger(eventName, this.context, eventObject);
  196. }
  197. return result;
  198. }
  199. // 初始化事件监听
  200. MarkControl.prototype.initTriggers = function(option) {
  201. if (this.triggers == undefined) {
  202. this.triggers = {};
  203. }
  204. if (option != undefined && option.on != undefined) {
  205. for (var name in option.on) {
  206. this.on(name, option.on[name]);
  207. }
  208. }
  209. var self = this;
  210. this.on('mark.sidebar.open', this, function(event, context, eventObject) {
  211. this.container.assistant.hide();
  212. if (this.container.center.hasClass('span12')) {
  213. this.container.center.removeClass('span12');
  214. this.container.center.addClass('span10');
  215. } else if (this.container.center.hasClass('span7')) {
  216. this.container.center.removeClass('span7');
  217. this.container.center.addClass('span5');
  218. }
  219. this.trigger('center.width.change');
  220. });
  221. this.on('mark.sidebar.close', this, function(event, context, eventObject) {
  222. this.container.assistant.hide();
  223. if (this.container.center.hasClass('span10')) {
  224. this.container.center.removeClass('span10');
  225. this.container.center.addClass('span12');
  226. } else if (this.container.center.hasClass('span5')) {
  227. this.container.center.removeClass('span5');
  228. this.container.center.addClass('span7');
  229. }
  230. this.trigger('center.width.change');
  231. });
  232. this.on('task.load.finish', this, function(event, context, eventObject) {
  233. self.container.centerNavbar.find('a:first').trigger('click');
  234. });
  235. this.on('mark.focus.change', this, function(event, context, eventObject) {
  236. });
  237. this.on('task.get.finish', this, function(event, context, eventObject) {
  238. context.prefetchCallback = undefined;
  239. });
  240. this.on('task.get.none', this, function(event, context, eventObject) {
  241. self.getStatus();
  242. if (context.task == undefined && self.option.clearUrl != undefined) {
  243. $.post(self.option.clearUrl, {}, function() {});
  244. }
  245. context.prefetchCallback = function() {
  246. context.prefetchCallback = undefined;
  247. if (self.context.task == undefined && self.context.prefetchTask.length > 0) {
  248. self.getTask();
  249. }
  250. }
  251. });
  252. this.on('task.prefetch.success', this, function(event, context, eventObject) {
  253. if (context.prefetchCallback != undefined) {
  254. context.prefetchCallback();
  255. }
  256. setTimeout(function() {
  257. self.prefetch();
  258. }, 500);
  259. });
  260. this.on('task.prefetch.error', this, function(event, context, eventObject) {
  261. setTimeout(function() {
  262. self.prefetch();
  263. }, 500);
  264. });
  265. this.on('task.prefetch.none', this, function(event, context, eventObject) {
  266. if (context.prefetchCallback != undefined) {
  267. context.prefetchCallback();
  268. }
  269. if (context.isFinish != true) {
  270. setTimeout(function() {
  271. self.prefetch();
  272. }, 1000);
  273. }
  274. });
  275. this.on('task.prefetch.finish', this, function(event, context, eventObject) {
  276. self.getTask();
  277. });
  278. this.on('task.submit.before', this, function(event, context, eventObject) {
  279. context.submitting = true;
  280. });
  281. this.on('history.submit.success', this, function(event, context, eventObject) {
  282. context.submitting = false;
  283. });
  284. this.on('task.submit.success', this, function(event, context, eventObject) {
  285. context.submitting = false;
  286. context.task = undefined;
  287. self.getTask();
  288. });
  289. this.on('task.submit.error', this, function(event, context, eventObject) {
  290. context.submitting = false;
  291. });
  292. this.on('task.pass.success', this, function(event, context, eventObject) {
  293. if (context.task != undefined && self.option.clearUrl != undefined) {
  294. $.post(self.option.clearUrl, {
  295. libraryId: context.task.libraryId
  296. });
  297. }
  298. context.task = undefined;
  299. self.getTask();
  300. });
  301. this.on('task.load.finish', this, function(event, context, eventObject) {
  302. var timestamp = new Date().getTime();
  303. context.task.spent = timestamp;
  304. });
  305. this.on('mark.setting.change', this, function(event, context, eventObject) {
  306. self.updateSetting(eventObject);
  307. });
  308. $(document).keypress(this, function(event) {
  309. if (self.context.listenKeyboard != false) {
  310. return self.trigger('key.press', event);
  311. }
  312. });
  313. $(document).keydown(this, function(event) {
  314. if (self.context.listenKeyboard != false) {
  315. return self.trigger('key.down', event);
  316. }
  317. });
  318. $(document).keyup(this, function(event) {
  319. if (self.context.listenKeyboard != false) {
  320. return self.trigger('key.up', event);
  321. }
  322. });
  323. window.onbeforeunload = function(e) {
  324. if (self.option.clearUrl != undefined) {
  325. $.post(self.option.clearUrl);
  326. }
  327. }
  328. }
  329. // 初始化功能模块
  330. MarkControl.prototype.initModules = function(option) {
  331. if (this.modules == undefined) {
  332. this.modules = {};
  333. }
  334. var names = [];
  335. var options = [];
  336. for (var name in this.defaultModules) {
  337. names.push(name);
  338. options[name] = this.defaultModules[name];
  339. }
  340. if (option.modules != undefined) {
  341. for (var name in option.modules) {
  342. if (options[name] == undefined) {
  343. names.push(name);
  344. options[name] = {};
  345. }
  346. $.extend(options[name], option.modules[name]);
  347. }
  348. }
  349. this.initModule(names, options, this.option.success);
  350. // initModule(this, names, 0, options);
  351. }
  352. // 指定初始化某个名称的模块
  353. MarkControl.prototype.initModule = function(names, options, success) {
  354. for (var i in names) {
  355. var name = names[i];
  356. var option = options[name];
  357. var moduleInit = name.replace(/-/g, '_');
  358. if (option == undefined || typeof(option) != 'object') {
  359. option = {};
  360. }
  361. option.markControl = this;
  362. eval('this.modules[name]=' + moduleInit + '(option, function(){})');
  363. }
  364. if (success != undefined && typeof(success) == 'function') {
  365. success();
  366. }
  367. }
  368. function initModuleAsync(markControl, names, index, option) {
  369. if (index < names.length) {
  370. var name = names[index];
  371. var moduleOption = option[name];
  372. var moduleUrl = 'modules/' + name + '.js';
  373. var moduleInit = name.replace(/-/g, '_');
  374. var modules = markControl.modules;
  375. if (modules[name] == undefined) {
  376. if (typeof(moduleOption) != 'object') {
  377. moduleOption = {};
  378. }
  379. moduleOption.markControl = markControl;
  380. $.getScript(moduleUrl, function() {
  381. var success = function() {
  382. initModule(markControl, names, index + 1, option);
  383. }
  384. eval('modules[name]=' + moduleInit + '(moduleOption, success)');
  385. });
  386. } else {
  387. initModule(markControl, names, index + 1, option);
  388. }
  389. } else {
  390. if (markControl.option.success != undefined && typeof(markControl.option.success) == 'function') {
  391. markControl.option.success();
  392. }
  393. }
  394. }
  395. MarkControl.prototype.start = function(taskOption) {
  396. taskOption.markControl = this;
  397. var markControl = this;
  398. taskOption.success = function() {
  399. markControl.context.prefetchCallback = function() {
  400. markControl.context.prefetchCallback = undefined;
  401. markControl.getTask();
  402. }
  403. markControl.context.statusCallback = function() {
  404. markControl.context.statusCallback = undefined;
  405. markControl.prefetch();
  406. }
  407. markControl.getStatus();
  408. };
  409. taskOption.error = function(message) {
  410. alert('初始化失败,请刷新页面重新加载');
  411. };
  412. this.taskControl = new TaskControl(taskOption);
  413. this.taskControl.init();
  414. }
  415. // task预加载
  416. MarkControl.prototype.prefetch = function() {
  417. var taskControl = this.taskControl;
  418. var markControl = this;
  419. var context = this.context;
  420. var imageBuilder = this.modules['image-builder'];
  421. if (context.isFinish != true) {
  422. if (taskControl.isFinish()) {
  423. context.isFinish = true;
  424. } else if (context.prefetchTask.length >= markControl.maxPrefetchCount) {
  425. markControl.trigger('task.prefetch.success');
  426. } else if (context.prefetching == false) {
  427. context.prefetching = true;
  428. markControl.trigger('task.prefetch.before');
  429. taskControl.fetch(function(task) {
  430. if (imageBuilder != undefined) {
  431. imageBuilder.build(task, function(error) {
  432. if (error) {
  433. context.prefetching = false;
  434. markControl.trigger('task.prefetch.error');
  435. } else {
  436. context.prefetchTask.push(task);
  437. context.prefetchStatus = undefined;
  438. context.prefetching = false;
  439. markControl.trigger('task.prefetch.success');
  440. }
  441. });
  442. } else {
  443. context.prefetchTask.push(task);
  444. context.prefetchStatus = undefined;
  445. context.prefetching = false;
  446. markControl.trigger('task.prefetch.success');
  447. }
  448. }, function(task) {
  449. context.prefetchStatus = task.message;
  450. context.prefetching = false;
  451. markControl.trigger('task.prefetch.none');
  452. }, function() {
  453. context.prefetching = false;
  454. markControl.trigger('task.prefetch.none');
  455. });
  456. }
  457. } else {
  458. markControl.trigger('task.prefetch.finish');
  459. }
  460. }
  461. MarkControl.prototype.getStatus = function() {
  462. if (this.taskControl == undefined) {
  463. return;
  464. }
  465. var self = this;
  466. this.taskControl.status(function(status) {
  467. self.context.status = status;
  468. if (status != undefined) {
  469. self.context.isFinish = status.blockTotalCount > 0 && status.blockTotalCount == (status.blockMarkedCount + status.blockExceptionCount);
  470. }
  471. if (self.context.statusCallback != undefined) {
  472. self.context.statusCallback();
  473. }
  474. self.trigger('mark.status.change', status);
  475. })
  476. }
  477. MarkControl.prototype.getTask = function() {
  478. if (this.taskControl == undefined) {
  479. return;
  480. }
  481. var markControl = this;
  482. var context = this.context;
  483. markControl.trigger('task.get.before');
  484. if (context.isFinish == true) {
  485. markControl.trigger('task.get.finish');
  486. return;
  487. } else if (context.task != undefined) {
  488. markControl.trigger('task.get.success');
  489. return;
  490. } else if (context.waitTask != undefined) {
  491. // 优先选择因回评等操作处于等待状态的任务
  492. context.task = context.waitTask;
  493. context.waitTask = undefined;
  494. markControl.trigger('task.get.success');
  495. } else if (context.prefetchTask.length > 0) {
  496. // 判断是否有任务已预加载完毕
  497. context.task = context.prefetchTask.shift();
  498. markControl.trigger('task.get.success');
  499. } else if (context.prefetchStatus != undefined) {
  500. // 判断是否有在无预加载任务的情况下的消息提示
  501. markControl.trigger('task.get.none', context.prefetchStatus);
  502. } else {
  503. markControl.trigger('task.get.none');
  504. }
  505. }
  506. MarkControl.prototype.getHistory = function(data) {
  507. if (this.taskControl == undefined) {
  508. return;
  509. }
  510. this.taskControl.history(data, function(result) {
  511. data.result = result;
  512. this.option.markControl.trigger('history.get.success', data);
  513. }, function(message) {
  514. data.message = message;
  515. this.option.markControl.trigger('history.get.error', data);
  516. });
  517. }
  518. MarkControl.prototype.setTask = function(task) {
  519. var imageBuilder = this.modules['image-builder'];
  520. var self = this;
  521. if (this.context.task != undefined && !this.context.task.previous && this.context.waitTask == undefined) {
  522. this.context.waitTask = this.context.task;
  523. }
  524. this.trigger('task.get.before');
  525. if (imageBuilder != undefined && task != undefined) {
  526. imageBuilder.build(task, function(error) {
  527. self.context.task = task;
  528. self.trigger('task.get.success');
  529. });
  530. } else {
  531. self.context.task = task;
  532. if (task != undefined) {
  533. this.trigger('task.get.success');
  534. }
  535. }
  536. }
  537. MarkControl.prototype.submitTask = function(submitUrl) {
  538. var task = this.context.task;
  539. var markControl = this;
  540. var submitUrl = submitUrl != undefined && submitUrl.length > 0 ? submitUrl : this.option.submitUrl;
  541. if (task != undefined && this.context.submitting != true) {
  542. //开启强制标记
  543. if(this.option.forceSpecialTag===true){
  544. var isTag = !(task.tagList==undefined ||task.tagList==null ||task.tagList.length <= 0);
  545. var isTrack = false;
  546. for(var i in task.trackList) {
  547. var track = task.trackList[i];
  548. if(track.positionX!=0 || track.positionY!=0 ){
  549. isTrack = true;
  550. }
  551. }
  552. if(!(isTag||isTrack)){
  553. markControl.trigger('task.submit.forceSpecialTag');
  554. return;
  555. }
  556. }
  557. var submitObj = {
  558. statusValue: task.statusValue,
  559. studentId: task.studentId,
  560. libraryId: task.libraryId,
  561. totalScore: task.totalScore,
  562. scoreList: task.scoreList,
  563. trackList: [],
  564. tagList: task.tagList,
  565. markId:task.markId,
  566. spent: new Date().getTime() - task.spent
  567. }
  568. this.trigger('task.submit.before');
  569. this.trigger('mark.specialTag.before');
  570. if (this.taskControl != undefined) {
  571. // 已定义任务引擎
  572. this.taskControl.submit(submitObj, function(status) {
  573. if (status != undefined && status.valid == true) {
  574. markControl.context.status = status;
  575. markControl.trigger('mark.status.change', status);
  576. }
  577. // markControl.context.task = undefined;
  578. if(task.previous==true){
  579. markControl.trigger('history.submit.success',task);
  580. }else{
  581. markControl.trigger('task.submit.success');
  582. }
  583. markControl.trigger('mark.specialTag.success');
  584. // markControl.getTask();
  585. }, function(message) {
  586. markControl.trigger('task.submit.error', message);
  587. });
  588. } else if (submitUrl != undefined && submitUrl.length > 0) {
  589. // 未定义任务引擎,依赖定义/传入的提交地址
  590. $.ajax({
  591. url: submitUrl,
  592. type: 'POST',
  593. data: task,
  594. success: function(result) {
  595. if (result.success == true) {
  596. // markControl.context.task = undefined;
  597. markControl.trigger('task.submit.success');
  598. markControl.trigger('mark.specialTag.success');
  599. // markControl.getTask();
  600. } else {
  601. markControl.trigger('task.submit.error', result.message);
  602. }
  603. },
  604. error: function(message) {
  605. markControl.trigger('task.submit.error', message);
  606. }
  607. });
  608. } else {
  609. markControl.trigger('task.submit.success');
  610. markControl.trigger('mark.specialTag.success');
  611. // markControl.getTask();
  612. }
  613. }
  614. }
  615. // 默认要初始化的模块名称
  616. MarkControl.prototype.defaultModules = {
  617. 'image-builder': {}
  618. };
  619. MarkControl.prototype.main_row_dom = '<div class="row-fluid"></div>';
  620. MarkControl.prototype.sidebar_dom = '<div class="mark-sidebar span2 hide"></div>';
  621. MarkControl.prototype.center_dom = '<div class="center-content span12"></div>';
  622. MarkControl.prototype.center_header_dom = '<div class="row-fluid"><div class="header"><p class="tips">\
  623. <em><a href="##" class="btn" id="switch-common-button" style="display:none">切换到普通模式</a>\
  624. <a href="javascript:void(0)" id="assistant-button" class="btn"><i class="icon-wrench"></i> 小助手</a></em>\
  625. <a class="clock" id="mark-clock"></a>\
  626. <a class="useinfo" href="#"><i class="icon-user icon-white"></i><i id="mark-user-name"></i></a>\
  627. <a class="logout" id="logout-link" href="{logoutUrl}"><i class="icon-off icon-white"></i> <i id="logout-title">退出</i></a>\
  628. </p></div></div>';
  629. MarkControl.prototype.center_content_dom = '<div class="row-fluid"><div class="image-content span9"><nav></nav></div></div>';
  630. MarkControl.prototype.assistant_dom = '<div class="popover bottom assistant"><div class="arrow"></div></div>';
  631. MarkControl.prototype.mark_function_dom = '<h3 class="popover-title">评卷功能</h3>\
  632. <div class="popover-content"><p id="function-list" class="popover-list">\
  633. </p></div>';
  634. MarkControl.prototype.mark_clock_dom = '<div class="clock_popover popover bottom assistant show">\
  635. <div class="arrow"></div>\
  636. <div class="popover-content"><p>阅卷时间:<em id="mark-time"></em></p></div>\
  637. </div>';
  638. // 其他通用方法
  639. String.prototype.startWith = function(prefix) {
  640. return this.indexOf(prefix) === 0;
  641. }
  642. String.prototype.endWith = function(suffix) {
  643. return this.match(suffix + "$") == suffix;
  644. };
  645. // 日期格式化
  646. Date.prototype.format = function(fmt) { // author: meizz
  647. var o = {
  648. "M+": this.getMonth() + 1, // 月份
  649. "d+": this.getDate(), // 日
  650. "h+": this.getHours(), // 小时
  651. "m+": this.getMinutes(), // 分
  652. "s+": this.getSeconds(), // 秒
  653. "q+": Math.floor((this.getMonth() + 3) / 3), // 季度
  654. "S": this.getMilliseconds() // 毫秒
  655. };
  656. if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  657. for (var k in o) {
  658. if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  659. }
  660. return fmt;
  661. }
  662. function getDom(content, markControl) {
  663. if (markControl != undefined && markControl.option.staticServer != undefined) {
  664. content = content.replace(/{staticServer}/g, markControl.option.staticServer);
  665. }
  666. if (markControl != undefined && markControl.option.logoutUrl != undefined) {
  667. content = content.replace(/{logoutUrl}/g, markControl.option.logoutUrl);
  668. }
  669. return $(content);
  670. }
  671. function isArray(obj) {
  672. return obj != undefined && Object.prototype.toString.call(obj) === '[object Array]';
  673. }