1
0

mark-control.js 27 KB

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