base64image.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. /*
  2. * Created by ALL-INKL.COM - Neue Medien Muennich - 04. Feb 2014
  3. * Licensed under the terms of GPL, LGPL and MPL licenses.
  4. */
  5. CKEDITOR.dialog.add("base64imageDialog", function(editor) {
  6. var t = null,
  7. selectedImg = null,
  8. orgWidth = null,
  9. orgHeight = null,
  10. imgPreview = null,
  11. urlCB = null,
  12. urlI = null,
  13. fileCB = null,
  14. imgScal = 1,
  15. lock = true;
  16. /* Check File Reader Support */
  17. function fileSupport() {
  18. var r = false,
  19. n = null;
  20. try {
  21. if (FileReader) {
  22. var n = document.createElement("input");
  23. if (n && "files" in n) r = true;
  24. }
  25. } catch (e) {
  26. r = false;
  27. }
  28. n = null;
  29. return r;
  30. }
  31. var fsupport = fileSupport();
  32. /* Load preview image */
  33. function imagePreviewLoad(s) {
  34. /* no preview */
  35. if (typeof s != "string" || !s) {
  36. imgPreview.getElement().setHtml("");
  37. return;
  38. }
  39. /* Create image */
  40. var i = new Image();
  41. /* Display loading text in preview element */
  42. imgPreview.getElement().setHtml("Loading...");
  43. /* When image is loaded */
  44. i.onload = function() {
  45. /* Remove preview */
  46. imgPreview.getElement().setHtml("");
  47. /* Set attributes */
  48. if (orgWidth == null || orgHeight == null) {
  49. t.setValueOf("tab-properties", "width", this.width);
  50. t.setValueOf("tab-properties", "height", this.height);
  51. imgScal = 1;
  52. if (this.height > 0 && this.width > 0)
  53. imgScal = this.width / this.height;
  54. if (imgScal <= 0) imgScal = 1;
  55. } else {
  56. orgWidth = null;
  57. orgHeight = null;
  58. }
  59. this.id = editor.id + "previewimage";
  60. this.setAttribute("style", "max-width:400px;max-height:100px;");
  61. this.setAttribute("alt", "");
  62. /* Insert preview image */
  63. try {
  64. var p = imgPreview.getElement().$;
  65. if (p) p.appendChild(this);
  66. } catch (e) {}
  67. };
  68. /* Error Function */
  69. i.onerror = function() {
  70. imgPreview.getElement().setHtml("");
  71. };
  72. i.onabort = function() {
  73. imgPreview.getElement().setHtml("");
  74. };
  75. /* Load image */
  76. i.src = s;
  77. }
  78. /* Change input values and preview image */
  79. function imagePreview(src) {
  80. /* Remove preview */
  81. imgPreview.getElement().setHtml("");
  82. if (src == "base64") {
  83. /* Disable Checkboxes */
  84. if (urlCB) urlCB.setValue(false, true);
  85. if (fileCB) fileCB.setValue(false, true);
  86. } else if (src == "url") {
  87. /* Ensable Image URL Checkbox */
  88. if (urlCB) urlCB.setValue(true, true);
  89. if (fileCB) fileCB.setValue(false, true);
  90. /* Load preview image */
  91. if (urlI) imagePreviewLoad(urlI.getValue());
  92. } else if (fsupport) {
  93. /* Ensable Image File Checkbox */
  94. if (urlCB) urlCB.setValue(false, true);
  95. if (fileCB) fileCB.setValue(true, true);
  96. /* Read file and load preview */
  97. var fileI = t.getContentElement("tab-source", "file");
  98. var n = null;
  99. try {
  100. n = fileI.getInputElement().$;
  101. } catch (e) {
  102. n = null;
  103. }
  104. if (n && "files" in n && n.files && n.files.length > 0 && n.files[0]) {
  105. if ("type" in n.files[0] && !n.files[0].type.match("image.*")) return;
  106. if (!FileReader) return;
  107. imgPreview.getElement().setHtml("Loading...");
  108. var fr = new FileReader();
  109. fr.onload = (function(f) {
  110. return function(e) {
  111. imgPreview.getElement().setHtml("");
  112. imagePreviewLoad(e.target.result);
  113. };
  114. })(n.files[0]);
  115. fr.onerror = function() {
  116. imgPreview.getElement().setHtml("");
  117. };
  118. fr.onabort = function() {
  119. imgPreview.getElement().setHtml("");
  120. };
  121. fr.readAsDataURL(n.files[0]);
  122. }
  123. }
  124. }
  125. /* Calculate image dimensions */
  126. function getImageDimensions() {
  127. var o = {
  128. w: t.getContentElement("tab-properties", "width").getValue(),
  129. h: t.getContentElement("tab-properties", "height").getValue(),
  130. uw: "px",
  131. uh: "px"
  132. };
  133. if (o.w.indexOf("%") >= 0) o.uw = "%";
  134. if (o.h.indexOf("%") >= 0) o.uh = "%";
  135. o.w = parseInt(o.w, 10);
  136. o.h = parseInt(o.h, 10);
  137. if (isNaN(o.w)) o.w = 0;
  138. if (isNaN(o.h)) o.h = 0;
  139. return o;
  140. }
  141. /* Set image dimensions */
  142. function imageDimensions(src) {
  143. var o = getImageDimensions();
  144. var u = "px";
  145. if (src == "width") {
  146. if (o.uw == "%") u = "%";
  147. o.h = Math.round(o.w / imgScal);
  148. } else {
  149. if (o.uh == "%") u = "%";
  150. o.w = Math.round(o.h * imgScal);
  151. }
  152. if (u == "%") {
  153. o.w += "%";
  154. o.h += "%";
  155. }
  156. t.getContentElement("tab-properties", "width").setValue(o.w),
  157. t.getContentElement("tab-properties", "height").setValue(o.h);
  158. }
  159. /* Set integer Value */
  160. function integerValue(elem) {
  161. var v = elem.getValue(),
  162. u = "";
  163. if (v.indexOf("%") >= 0) u = "%";
  164. v = parseInt(v, 10);
  165. if (isNaN(v)) v = 0;
  166. elem.setValue(v + u);
  167. }
  168. if (fsupport) {
  169. /* Dialog with file and url image source */
  170. var sourceElements = [
  171. {
  172. type: "hbox",
  173. widths: ["70px"],
  174. children: [
  175. {
  176. type: "checkbox",
  177. id: "urlcheckbox",
  178. style: "margin-top:5px",
  179. label: editor.lang.common.url + ":"
  180. },
  181. {
  182. type: "text",
  183. id: "url",
  184. label: "",
  185. onChange: function() {
  186. imagePreview("url");
  187. }
  188. }
  189. ]
  190. },
  191. {
  192. type: "hbox",
  193. widths: ["70px"],
  194. children: [
  195. {
  196. type: "checkbox",
  197. id: "filecheckbox",
  198. style: "margin-top:5px",
  199. label: editor.lang.common.upload + ":"
  200. },
  201. {
  202. type: "file",
  203. id: "file",
  204. label: "",
  205. onChange: function() {
  206. imagePreview("file");
  207. }
  208. }
  209. ]
  210. },
  211. {
  212. type: "html",
  213. id: "preview",
  214. html: new CKEDITOR.template(
  215. '<div style="text-align:center;"></div>'
  216. ).output()
  217. }
  218. ];
  219. } else {
  220. /* Dialog with url image source */
  221. var sourceElements = [
  222. {
  223. type: "text",
  224. id: "url",
  225. label: editor.lang.common.url,
  226. onChange: function() {
  227. imagePreview("url");
  228. }
  229. },
  230. {
  231. type: "html",
  232. id: "preview",
  233. html: new CKEDITOR.template(
  234. '<div style="text-align:center;"></div>'
  235. ).output()
  236. }
  237. ];
  238. }
  239. /* Dialog */
  240. return {
  241. title: editor.lang.common.image,
  242. minWidth: 450,
  243. minHeight: 180,
  244. onLoad: function() {
  245. if (fsupport) {
  246. /* Get checkboxes */
  247. urlCB = this.getContentElement("tab-source", "urlcheckbox");
  248. fileCB = this.getContentElement("tab-source", "filecheckbox");
  249. /* Checkbox Events */
  250. urlCB.getInputElement().on("click", function() {
  251. imagePreview("url");
  252. });
  253. fileCB.getInputElement().on("click", function() {
  254. imagePreview("file");
  255. });
  256. }
  257. /* Get url input element */
  258. urlI = this.getContentElement("tab-source", "url");
  259. /* Get image preview element */
  260. imgPreview = this.getContentElement("tab-source", "preview");
  261. /* Constrain proportions or not */
  262. this.getContentElement("tab-properties", "lock")
  263. .getInputElement()
  264. .on(
  265. "click",
  266. function() {
  267. if (this.getValue()) lock = true;
  268. else lock = false;
  269. if (lock) imageDimensions("width");
  270. },
  271. this.getContentElement("tab-properties", "lock")
  272. );
  273. /* Change Attributes Events */
  274. this.getContentElement("tab-properties", "width")
  275. .getInputElement()
  276. .on("keyup", function() {
  277. if (lock) imageDimensions("width");
  278. });
  279. this.getContentElement("tab-properties", "height")
  280. .getInputElement()
  281. .on("keyup", function() {
  282. if (lock) imageDimensions("height");
  283. });
  284. this.getContentElement("tab-properties", "vmargin")
  285. .getInputElement()
  286. .on(
  287. "keyup",
  288. function() {
  289. integerValue(this);
  290. },
  291. this.getContentElement("tab-properties", "vmargin")
  292. );
  293. this.getContentElement("tab-properties", "hmargin")
  294. .getInputElement()
  295. .on(
  296. "keyup",
  297. function() {
  298. integerValue(this);
  299. },
  300. this.getContentElement("tab-properties", "hmargin")
  301. );
  302. this.getContentElement("tab-properties", "border")
  303. .getInputElement()
  304. .on(
  305. "keyup",
  306. function() {
  307. integerValue(this);
  308. },
  309. this.getContentElement("tab-properties", "border")
  310. );
  311. },
  312. onShow: function() {
  313. /* Remove preview */
  314. imgPreview.getElement().setHtml("");
  315. (t = this),
  316. (orgWidth = null),
  317. (orgHeight = null),
  318. (imgScal = 1),
  319. (lock = true);
  320. /* selected image or null */
  321. selectedImg = editor.getSelection();
  322. if (selectedImg) selectedImg = selectedImg.getSelectedElement();
  323. if (!selectedImg || selectedImg.getName() !== "img") selectedImg = null;
  324. /* Set input values */
  325. t.setValueOf("tab-properties", "lock", lock);
  326. t.setValueOf("tab-properties", "vmargin", "0");
  327. t.setValueOf("tab-properties", "hmargin", "0");
  328. t.setValueOf("tab-properties", "border", "0");
  329. t.setValueOf("tab-properties", "align", "none");
  330. if (selectedImg) {
  331. /* Set input values from selected image */
  332. if (typeof selectedImg.getAttribute("width") == "string")
  333. orgWidth = selectedImg.getAttribute("width");
  334. if (typeof selectedImg.getAttribute("height") == "string")
  335. orgHeight = selectedImg.getAttribute("height");
  336. if ((orgWidth == null || orgHeight == null) && selectedImg.$) {
  337. orgWidth = selectedImg.$.width;
  338. orgHeight = selectedImg.$.height;
  339. }
  340. if (orgWidth != null && orgHeight != null) {
  341. t.setValueOf("tab-properties", "width", orgWidth);
  342. t.setValueOf("tab-properties", "height", orgHeight);
  343. orgWidth = parseInt(orgWidth, 10);
  344. orgHeight = parseInt(orgHeight, 10);
  345. imgScal = 1;
  346. if (
  347. !isNaN(orgWidth) &&
  348. !isNaN(orgHeight) &&
  349. orgHeight > 0 &&
  350. orgWidth > 0
  351. )
  352. imgScal = orgWidth / orgHeight;
  353. if (imgScal <= 0) imgScal = 1;
  354. }
  355. if (typeof selectedImg.getAttribute("src") == "string") {
  356. if (selectedImg.getAttribute("src").indexOf("data:") === 0) {
  357. imagePreview("base64");
  358. imagePreviewLoad(selectedImg.getAttribute("src"));
  359. } else {
  360. t.setValueOf("tab-source", "url", selectedImg.getAttribute("src"));
  361. }
  362. }
  363. if (typeof selectedImg.getAttribute("alt") == "string")
  364. t.setValueOf(
  365. "tab-properties",
  366. "alt",
  367. selectedImg.getAttribute("alt")
  368. );
  369. if (typeof selectedImg.getAttribute("hspace") == "string")
  370. t.setValueOf(
  371. "tab-properties",
  372. "hmargin",
  373. selectedImg.getAttribute("hspace")
  374. );
  375. if (typeof selectedImg.getAttribute("vspace") == "string")
  376. t.setValueOf(
  377. "tab-properties",
  378. "vmargin",
  379. selectedImg.getAttribute("vspace")
  380. );
  381. if (typeof selectedImg.getAttribute("border") == "string")
  382. t.setValueOf(
  383. "tab-properties",
  384. "border",
  385. selectedImg.getAttribute("border")
  386. );
  387. if (typeof selectedImg.getAttribute("align") == "string") {
  388. switch (selectedImg.getAttribute("align")) {
  389. case "top":
  390. case "text-top":
  391. t.setValueOf("tab-properties", "align", "top");
  392. break;
  393. case "baseline":
  394. case "bottom":
  395. case "text-bottom":
  396. t.setValueOf("tab-properties", "align", "bottom");
  397. break;
  398. case "left":
  399. t.setValueOf("tab-properties", "align", "left");
  400. break;
  401. case "right":
  402. t.setValueOf("tab-properties", "align", "right");
  403. break;
  404. }
  405. }
  406. t.selectPage("tab-properties");
  407. }
  408. },
  409. onOk: function() {
  410. /* Get image source */
  411. var src = "";
  412. try {
  413. src = CKEDITOR.document.getById(editor.id + "previewimage").$.src;
  414. } catch (e) {
  415. src = "";
  416. }
  417. if (typeof src != "string" || src == null || src === "") return;
  418. /* selected image or new image */
  419. if (selectedImg) var newImg = selectedImg;
  420. else var newImg = editor.document.createElement("img");
  421. newImg.setAttribute("src", src);
  422. src = null;
  423. /* Set attributes */
  424. newImg.setAttribute(
  425. "alt",
  426. t
  427. .getValueOf("tab-properties", "alt")
  428. .replace(/^\s+/, "")
  429. .replace(/\s+$/, "")
  430. );
  431. var attr = {
  432. width: ["width", "width:#;", "integer", 1],
  433. height: ["height", "height:#;", "integer", 1],
  434. vmargin: ["vspace", "margin-top:#;margin-bottom:#;", "integer", 0],
  435. hmargin: ["hspace", "margin-left:#;margin-right:#;", "integer", 0],
  436. align: ["align", ""],
  437. border: ["border", "border:# solid black;", "integer", 0]
  438. },
  439. css = [],
  440. value,
  441. cssvalue,
  442. attrvalue,
  443. k;
  444. for (k in attr) {
  445. value = t.getValueOf("tab-properties", k);
  446. attrvalue = value;
  447. cssvalue = value;
  448. unit = "px";
  449. if (k == "align") {
  450. switch (value) {
  451. case "top":
  452. case "bottom":
  453. attr[k][1] = "vertical-align:#;";
  454. break;
  455. case "left":
  456. case "right":
  457. attr[k][1] = "float:#;";
  458. break;
  459. default:
  460. value = null;
  461. break;
  462. }
  463. }
  464. if (attr[k][2] == "integer") {
  465. if (value.indexOf("%") >= 0) unit = "%";
  466. value = parseInt(value, 10);
  467. if (isNaN(value)) value = null;
  468. else if (value < attr[k][3]) value = null;
  469. if (value != null) {
  470. if (unit == "%") {
  471. attrvalue = value + "%";
  472. cssvalue = value + "%";
  473. } else {
  474. attrvalue = value;
  475. cssvalue = value + "px";
  476. }
  477. }
  478. }
  479. if (value != null) {
  480. newImg.setAttribute(attr[k][0], attrvalue);
  481. css.push(attr[k][1].replace(/#/g, cssvalue));
  482. }
  483. }
  484. if (css.length > 0) newImg.setAttribute("style", css.join(""));
  485. /* Insert new image */
  486. if (!selectedImg) editor.insertElement(newImg);
  487. /* Resize image */
  488. if (editor.plugins.imageresize)
  489. editor.plugins.imageresize.resize(editor, newImg, 800, 800);
  490. editor.setData(editor.getData());
  491. },
  492. /* Dialog form */
  493. contents: [
  494. {
  495. id: "tab-source",
  496. label: editor.lang.common.generalTab,
  497. elements: sourceElements
  498. },
  499. {
  500. id: "tab-properties",
  501. label: editor.lang.common.advancedTab,
  502. elements: [
  503. {
  504. type: "text",
  505. id: "alt",
  506. label: editor.lang.base64image.alt
  507. },
  508. {
  509. type: "hbox",
  510. widths: ["15%", "15%", "70%"],
  511. children: [
  512. {
  513. type: "text",
  514. width: "45px",
  515. id: "width",
  516. label: editor.lang.common.width
  517. },
  518. {
  519. type: "text",
  520. width: "45px",
  521. id: "height",
  522. label: editor.lang.common.height
  523. },
  524. {
  525. type: "checkbox",
  526. id: "lock",
  527. label: editor.lang.base64image.lockRatio,
  528. style: "margin-top:18px;"
  529. }
  530. ]
  531. },
  532. {
  533. type: "hbox",
  534. widths: ["23%", "30%", "30%", "17%"],
  535. style: "margin-top:10px;",
  536. children: [
  537. {
  538. type: "select",
  539. id: "align",
  540. label: editor.lang.common.align,
  541. items: [
  542. [editor.lang.common.notSet, "none"],
  543. [editor.lang.common.alignTop, "top"],
  544. [editor.lang.common.alignBottom, "bottom"],
  545. [editor.lang.common.alignLeft, "left"],
  546. [editor.lang.common.alignRight, "right"]
  547. ]
  548. },
  549. {
  550. type: "text",
  551. width: "45px",
  552. id: "vmargin",
  553. label: editor.lang.base64image.vSpace
  554. },
  555. {
  556. type: "text",
  557. width: "45px",
  558. id: "hmargin",
  559. label: editor.lang.base64image.hSpace
  560. },
  561. {
  562. type: "text",
  563. width: "45px",
  564. id: "border",
  565. label: editor.lang.base64image.border
  566. }
  567. ]
  568. }
  569. ]
  570. }
  571. ]
  572. };
  573. });