plugin.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. (function () {
  2. var fullpage = (function () {
  3. 'use strict';
  4. var Cell = function (initial) {
  5. var value = initial;
  6. var get = function () {
  7. return value;
  8. };
  9. var set = function (v) {
  10. value = v;
  11. };
  12. var clone = function () {
  13. return Cell(get());
  14. };
  15. return {
  16. get: get,
  17. set: set,
  18. clone: clone
  19. };
  20. };
  21. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  22. var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools');
  23. var global$2 = tinymce.util.Tools.resolve('tinymce.html.DomParser');
  24. var global$3 = tinymce.util.Tools.resolve('tinymce.html.Node');
  25. var global$4 = tinymce.util.Tools.resolve('tinymce.html.Serializer');
  26. var shouldHideInSourceView = function (editor) {
  27. return editor.getParam('fullpage_hide_in_source_view');
  28. };
  29. var getDefaultXmlPi = function (editor) {
  30. return editor.getParam('fullpage_default_xml_pi');
  31. };
  32. var getDefaultEncoding = function (editor) {
  33. return editor.getParam('fullpage_default_encoding');
  34. };
  35. var getDefaultFontFamily = function (editor) {
  36. return editor.getParam('fullpage_default_font_family');
  37. };
  38. var getDefaultFontSize = function (editor) {
  39. return editor.getParam('fullpage_default_font_size');
  40. };
  41. var getDefaultTextColor = function (editor) {
  42. return editor.getParam('fullpage_default_text_color');
  43. };
  44. var getDefaultTitle = function (editor) {
  45. return editor.getParam('fullpage_default_title');
  46. };
  47. var getDefaultDocType = function (editor) {
  48. return editor.getParam('fullpage_default_doctype', '<!DOCTYPE html>');
  49. };
  50. var $_7rjdl7c7jkmcwoj4 = {
  51. shouldHideInSourceView: shouldHideInSourceView,
  52. getDefaultXmlPi: getDefaultXmlPi,
  53. getDefaultEncoding: getDefaultEncoding,
  54. getDefaultFontFamily: getDefaultFontFamily,
  55. getDefaultFontSize: getDefaultFontSize,
  56. getDefaultTextColor: getDefaultTextColor,
  57. getDefaultTitle: getDefaultTitle,
  58. getDefaultDocType: getDefaultDocType
  59. };
  60. var parseHeader = function (head) {
  61. return global$2({
  62. validate: false,
  63. root_name: '#document'
  64. }).parse(head);
  65. };
  66. var htmlToData = function (editor, head) {
  67. var headerFragment = parseHeader(head);
  68. var data = {};
  69. var elm, matches;
  70. function getAttr(elm, name) {
  71. var value = elm.attr(name);
  72. return value || '';
  73. }
  74. data.fontface = $_7rjdl7c7jkmcwoj4.getDefaultFontFamily(editor);
  75. data.fontsize = $_7rjdl7c7jkmcwoj4.getDefaultFontSize(editor);
  76. elm = headerFragment.firstChild;
  77. if (elm.type === 7) {
  78. data.xml_pi = true;
  79. matches = /encoding="([^"]+)"/.exec(elm.value);
  80. if (matches) {
  81. data.docencoding = matches[1];
  82. }
  83. }
  84. elm = headerFragment.getAll('#doctype')[0];
  85. if (elm) {
  86. data.doctype = '<!DOCTYPE' + elm.value + '>';
  87. }
  88. elm = headerFragment.getAll('title')[0];
  89. if (elm && elm.firstChild) {
  90. data.title = elm.firstChild.value;
  91. }
  92. global$1.each(headerFragment.getAll('meta'), function (meta) {
  93. var name = meta.attr('name');
  94. var httpEquiv = meta.attr('http-equiv');
  95. var matches;
  96. if (name) {
  97. data[name.toLowerCase()] = meta.attr('content');
  98. } else if (httpEquiv === 'Content-Type') {
  99. matches = /charset\s*=\s*(.*)\s*/gi.exec(meta.attr('content'));
  100. if (matches) {
  101. data.docencoding = matches[1];
  102. }
  103. }
  104. });
  105. elm = headerFragment.getAll('html')[0];
  106. if (elm) {
  107. data.langcode = getAttr(elm, 'lang') || getAttr(elm, 'xml:lang');
  108. }
  109. data.stylesheets = [];
  110. global$1.each(headerFragment.getAll('link'), function (link) {
  111. if (link.attr('rel') === 'stylesheet') {
  112. data.stylesheets.push(link.attr('href'));
  113. }
  114. });
  115. elm = headerFragment.getAll('body')[0];
  116. if (elm) {
  117. data.langdir = getAttr(elm, 'dir');
  118. data.style = getAttr(elm, 'style');
  119. data.visited_color = getAttr(elm, 'vlink');
  120. data.link_color = getAttr(elm, 'link');
  121. data.active_color = getAttr(elm, 'alink');
  122. }
  123. return data;
  124. };
  125. var dataToHtml = function (editor, data, head) {
  126. var headerFragment, headElement, html, elm, value;
  127. var dom = editor.dom;
  128. function setAttr(elm, name, value) {
  129. elm.attr(name, value ? value : undefined);
  130. }
  131. function addHeadNode(node) {
  132. if (headElement.firstChild) {
  133. headElement.insert(node, headElement.firstChild);
  134. } else {
  135. headElement.append(node);
  136. }
  137. }
  138. headerFragment = parseHeader(head);
  139. headElement = headerFragment.getAll('head')[0];
  140. if (!headElement) {
  141. elm = headerFragment.getAll('html')[0];
  142. headElement = new global$3('head', 1);
  143. if (elm.firstChild) {
  144. elm.insert(headElement, elm.firstChild, true);
  145. } else {
  146. elm.append(headElement);
  147. }
  148. }
  149. elm = headerFragment.firstChild;
  150. if (data.xml_pi) {
  151. value = 'version="1.0"';
  152. if (data.docencoding) {
  153. value += ' encoding="' + data.docencoding + '"';
  154. }
  155. if (elm.type !== 7) {
  156. elm = new global$3('xml', 7);
  157. headerFragment.insert(elm, headerFragment.firstChild, true);
  158. }
  159. elm.value = value;
  160. } else if (elm && elm.type === 7) {
  161. elm.remove();
  162. }
  163. elm = headerFragment.getAll('#doctype')[0];
  164. if (data.doctype) {
  165. if (!elm) {
  166. elm = new global$3('#doctype', 10);
  167. if (data.xml_pi) {
  168. headerFragment.insert(elm, headerFragment.firstChild);
  169. } else {
  170. addHeadNode(elm);
  171. }
  172. }
  173. elm.value = data.doctype.substring(9, data.doctype.length - 1);
  174. } else if (elm) {
  175. elm.remove();
  176. }
  177. elm = null;
  178. global$1.each(headerFragment.getAll('meta'), function (meta) {
  179. if (meta.attr('http-equiv') === 'Content-Type') {
  180. elm = meta;
  181. }
  182. });
  183. if (data.docencoding) {
  184. if (!elm) {
  185. elm = new global$3('meta', 1);
  186. elm.attr('http-equiv', 'Content-Type');
  187. elm.shortEnded = true;
  188. addHeadNode(elm);
  189. }
  190. elm.attr('content', 'text/html; charset=' + data.docencoding);
  191. } else if (elm) {
  192. elm.remove();
  193. }
  194. elm = headerFragment.getAll('title')[0];
  195. if (data.title) {
  196. if (!elm) {
  197. elm = new global$3('title', 1);
  198. addHeadNode(elm);
  199. } else {
  200. elm.empty();
  201. }
  202. elm.append(new global$3('#text', 3)).value = data.title;
  203. } else if (elm) {
  204. elm.remove();
  205. }
  206. global$1.each('keywords,description,author,copyright,robots'.split(','), function (name) {
  207. var nodes = headerFragment.getAll('meta');
  208. var i, meta;
  209. var value = data[name];
  210. for (i = 0; i < nodes.length; i++) {
  211. meta = nodes[i];
  212. if (meta.attr('name') === name) {
  213. if (value) {
  214. meta.attr('content', value);
  215. } else {
  216. meta.remove();
  217. }
  218. return;
  219. }
  220. }
  221. if (value) {
  222. elm = new global$3('meta', 1);
  223. elm.attr('name', name);
  224. elm.attr('content', value);
  225. elm.shortEnded = true;
  226. addHeadNode(elm);
  227. }
  228. });
  229. var currentStyleSheetsMap = {};
  230. global$1.each(headerFragment.getAll('link'), function (stylesheet) {
  231. if (stylesheet.attr('rel') === 'stylesheet') {
  232. currentStyleSheetsMap[stylesheet.attr('href')] = stylesheet;
  233. }
  234. });
  235. global$1.each(data.stylesheets, function (stylesheet) {
  236. if (!currentStyleSheetsMap[stylesheet]) {
  237. elm = new global$3('link', 1);
  238. elm.attr({
  239. rel: 'stylesheet',
  240. text: 'text/css',
  241. href: stylesheet
  242. });
  243. elm.shortEnded = true;
  244. addHeadNode(elm);
  245. }
  246. delete currentStyleSheetsMap[stylesheet];
  247. });
  248. global$1.each(currentStyleSheetsMap, function (stylesheet) {
  249. stylesheet.remove();
  250. });
  251. elm = headerFragment.getAll('body')[0];
  252. if (elm) {
  253. setAttr(elm, 'dir', data.langdir);
  254. setAttr(elm, 'style', data.style);
  255. setAttr(elm, 'vlink', data.visited_color);
  256. setAttr(elm, 'link', data.link_color);
  257. setAttr(elm, 'alink', data.active_color);
  258. dom.setAttribs(editor.getBody(), {
  259. style: data.style,
  260. dir: data.dir,
  261. vLink: data.visited_color,
  262. link: data.link_color,
  263. aLink: data.active_color
  264. });
  265. }
  266. elm = headerFragment.getAll('html')[0];
  267. if (elm) {
  268. setAttr(elm, 'lang', data.langcode);
  269. setAttr(elm, 'xml:lang', data.langcode);
  270. }
  271. if (!headElement.firstChild) {
  272. headElement.remove();
  273. }
  274. html = global$4({
  275. validate: false,
  276. indent: true,
  277. apply_source_formatting: true,
  278. indent_before: 'head,html,body,meta,title,script,link,style',
  279. indent_after: 'head,html,body,meta,title,script,link,style'
  280. }).serialize(headerFragment);
  281. return html.substring(0, html.indexOf('</body>'));
  282. };
  283. var $_5rofa0c3jkmcwoix = {
  284. parseHeader: parseHeader,
  285. htmlToData: htmlToData,
  286. dataToHtml: dataToHtml
  287. };
  288. var open = function (editor, headState) {
  289. var data = $_5rofa0c3jkmcwoix.htmlToData(editor, headState.get());
  290. editor.windowManager.open({
  291. title: 'Document properties',
  292. data: data,
  293. defaults: {
  294. type: 'textbox',
  295. size: 40
  296. },
  297. body: [
  298. {
  299. name: 'title',
  300. label: 'Title'
  301. },
  302. {
  303. name: 'keywords',
  304. label: 'Keywords'
  305. },
  306. {
  307. name: 'description',
  308. label: 'Description'
  309. },
  310. {
  311. name: 'robots',
  312. label: 'Robots'
  313. },
  314. {
  315. name: 'author',
  316. label: 'Author'
  317. },
  318. {
  319. name: 'docencoding',
  320. label: 'Encoding'
  321. }
  322. ],
  323. onSubmit: function (e) {
  324. var headHtml = $_5rofa0c3jkmcwoix.dataToHtml(editor, global$1.extend(data, e.data), headState.get());
  325. headState.set(headHtml);
  326. }
  327. });
  328. };
  329. var $_7mvolec1jkmcwoit = { open: open };
  330. var register = function (editor, headState) {
  331. editor.addCommand('mceFullPageProperties', function () {
  332. $_7mvolec1jkmcwoit.open(editor, headState);
  333. });
  334. };
  335. var $_4a9ny4c0jkmcwoir = { register: register };
  336. var protectHtml = function (protect, html) {
  337. global$1.each(protect, function (pattern) {
  338. html = html.replace(pattern, function (str) {
  339. return '<!--mce:protected ' + escape(str) + '-->';
  340. });
  341. });
  342. return html;
  343. };
  344. var unprotectHtml = function (html) {
  345. return html.replace(/<!--mce:protected ([\s\S]*?)-->/g, function (a, m) {
  346. return unescape(m);
  347. });
  348. };
  349. var $_7stjxwc9jkmcwoja = {
  350. protectHtml: protectHtml,
  351. unprotectHtml: unprotectHtml
  352. };
  353. var each = global$1.each;
  354. var low = function (s) {
  355. return s.replace(/<\/?[A-Z]+/g, function (a) {
  356. return a.toLowerCase();
  357. });
  358. };
  359. var handleSetContent = function (editor, headState, footState, evt) {
  360. var startPos, endPos, content, headerFragment, styles = '';
  361. var dom = editor.dom;
  362. var elm;
  363. if (evt.selection) {
  364. return;
  365. }
  366. content = $_7stjxwc9jkmcwoja.protectHtml(editor.settings.protect, evt.content);
  367. if (evt.format === 'raw' && headState.get()) {
  368. return;
  369. }
  370. if (evt.source_view && $_7rjdl7c7jkmcwoj4.shouldHideInSourceView(editor)) {
  371. return;
  372. }
  373. if (content.length === 0 && !evt.source_view) {
  374. content = global$1.trim(headState.get()) + '\n' + global$1.trim(content) + '\n' + global$1.trim(footState.get());
  375. }
  376. content = content.replace(/<(\/?)BODY/gi, '<$1body');
  377. startPos = content.indexOf('<body');
  378. if (startPos !== -1) {
  379. startPos = content.indexOf('>', startPos);
  380. headState.set(low(content.substring(0, startPos + 1)));
  381. endPos = content.indexOf('</body', startPos);
  382. if (endPos === -1) {
  383. endPos = content.length;
  384. }
  385. evt.content = global$1.trim(content.substring(startPos + 1, endPos));
  386. footState.set(low(content.substring(endPos)));
  387. } else {
  388. headState.set(getDefaultHeader(editor));
  389. footState.set('\n</body>\n</html>');
  390. }
  391. headerFragment = $_5rofa0c3jkmcwoix.parseHeader(headState.get());
  392. each(headerFragment.getAll('style'), function (node) {
  393. if (node.firstChild) {
  394. styles += node.firstChild.value;
  395. }
  396. });
  397. elm = headerFragment.getAll('body')[0];
  398. if (elm) {
  399. dom.setAttribs(editor.getBody(), {
  400. style: elm.attr('style') || '',
  401. dir: elm.attr('dir') || '',
  402. vLink: elm.attr('vlink') || '',
  403. link: elm.attr('link') || '',
  404. aLink: elm.attr('alink') || ''
  405. });
  406. }
  407. dom.remove('fullpage_styles');
  408. var headElm = editor.getDoc().getElementsByTagName('head')[0];
  409. if (styles) {
  410. dom.add(headElm, 'style', { id: 'fullpage_styles' }, styles);
  411. elm = dom.get('fullpage_styles');
  412. if (elm.styleSheet) {
  413. elm.styleSheet.cssText = styles;
  414. }
  415. }
  416. var currentStyleSheetsMap = {};
  417. global$1.each(headElm.getElementsByTagName('link'), function (stylesheet) {
  418. if (stylesheet.rel === 'stylesheet' && stylesheet.getAttribute('data-mce-fullpage')) {
  419. currentStyleSheetsMap[stylesheet.href] = stylesheet;
  420. }
  421. });
  422. global$1.each(headerFragment.getAll('link'), function (stylesheet) {
  423. var href = stylesheet.attr('href');
  424. if (!href) {
  425. return true;
  426. }
  427. if (!currentStyleSheetsMap[href] && stylesheet.attr('rel') === 'stylesheet') {
  428. dom.add(headElm, 'link', {
  429. 'rel': 'stylesheet',
  430. 'text': 'text/css',
  431. 'href': href,
  432. 'data-mce-fullpage': '1'
  433. });
  434. }
  435. delete currentStyleSheetsMap[href];
  436. });
  437. global$1.each(currentStyleSheetsMap, function (stylesheet) {
  438. stylesheet.parentNode.removeChild(stylesheet);
  439. });
  440. };
  441. var getDefaultHeader = function (editor) {
  442. var header = '', value, styles = '';
  443. if ($_7rjdl7c7jkmcwoj4.getDefaultXmlPi(editor)) {
  444. var piEncoding = $_7rjdl7c7jkmcwoj4.getDefaultEncoding(editor);
  445. header += '<?xml version="1.0" encoding="' + (piEncoding ? piEncoding : 'ISO-8859-1') + '" ?>\n';
  446. }
  447. header += $_7rjdl7c7jkmcwoj4.getDefaultDocType(editor);
  448. header += '\n<html>\n<head>\n';
  449. if (value = $_7rjdl7c7jkmcwoj4.getDefaultTitle(editor)) {
  450. header += '<title>' + value + '</title>\n';
  451. }
  452. if (value = $_7rjdl7c7jkmcwoj4.getDefaultEncoding(editor)) {
  453. header += '<meta http-equiv="Content-Type" content="text/html; charset=' + value + '" />\n';
  454. }
  455. if (value = $_7rjdl7c7jkmcwoj4.getDefaultFontFamily(editor)) {
  456. styles += 'font-family: ' + value + ';';
  457. }
  458. if (value = $_7rjdl7c7jkmcwoj4.getDefaultFontSize(editor)) {
  459. styles += 'font-size: ' + value + ';';
  460. }
  461. if (value = $_7rjdl7c7jkmcwoj4.getDefaultTextColor(editor)) {
  462. styles += 'color: ' + value + ';';
  463. }
  464. header += '</head>\n<body' + (styles ? ' style="' + styles + '"' : '') + '>\n';
  465. return header;
  466. };
  467. var handleGetContent = function (editor, head, foot, evt) {
  468. if (!evt.selection && (!evt.source_view || !$_7rjdl7c7jkmcwoj4.shouldHideInSourceView(editor))) {
  469. evt.content = $_7stjxwc9jkmcwoja.unprotectHtml(global$1.trim(head) + '\n' + global$1.trim(evt.content) + '\n' + global$1.trim(foot));
  470. }
  471. };
  472. var setup = function (editor, headState, footState) {
  473. editor.on('BeforeSetContent', function (evt) {
  474. handleSetContent(editor, headState, footState, evt);
  475. });
  476. editor.on('GetContent', function (evt) {
  477. handleGetContent(editor, headState.get(), footState.get(), evt);
  478. });
  479. };
  480. var $_9yn4mc8jkmcwoj6 = { setup: setup };
  481. var register$1 = function (editor) {
  482. editor.addButton('fullpage', {
  483. title: 'Document properties',
  484. cmd: 'mceFullPageProperties'
  485. });
  486. editor.addMenuItem('fullpage', {
  487. text: 'Document properties',
  488. cmd: 'mceFullPageProperties',
  489. context: 'file'
  490. });
  491. };
  492. var $_ai61ducajkmcwojc = { register: register$1 };
  493. global.add('fullpage', function (editor) {
  494. var headState = Cell(''), footState = Cell('');
  495. $_4a9ny4c0jkmcwoir.register(editor, headState);
  496. $_ai61ducajkmcwojc.register(editor);
  497. $_9yn4mc8jkmcwoj6.setup(editor, headState, footState);
  498. });
  499. function Plugin () {
  500. }
  501. return Plugin;
  502. }());
  503. })();