editor.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. ///import core
  2. ///commands 全屏
  3. ///commandsName FullScreen
  4. ///commandsTitle 全屏
  5. (function() {
  6. var utils = baidu.editor.utils,
  7. uiUtils = baidu.editor.ui.uiUtils,
  8. UIBase = baidu.editor.ui.UIBase,
  9. domUtils = baidu.editor.dom.domUtils;
  10. var nodeStack = [];
  11. function EditorUI(options) {
  12. this.initOptions(options);
  13. this.initEditorUI();
  14. }
  15. EditorUI.prototype = {
  16. uiName: "editor",
  17. initEditorUI: function() {
  18. this.editor.ui = this;
  19. this._dialogs = {};
  20. this.initUIBase();
  21. this._initToolbars();
  22. var editor = this.editor,
  23. me = this;
  24. editor.addListener("ready", function() {
  25. //提供getDialog方法
  26. editor.getDialog = function(name) {
  27. return editor.ui._dialogs[name + "Dialog"];
  28. };
  29. domUtils.on(editor.window, "scroll", function(evt) {
  30. baidu.editor.ui.Popup.postHide(evt);
  31. });
  32. //提供编辑器实时宽高(全屏时宽高不变化)
  33. editor.ui._actualFrameWidth = editor.options.initialFrameWidth;
  34. UE.browser.ie &&
  35. UE.browser.version === 6 &&
  36. editor.container.ownerDocument.execCommand(
  37. "BackgroundImageCache",
  38. false,
  39. true
  40. );
  41. //display bottom-bar label based on config
  42. if (editor.options.elementPathEnabled) {
  43. editor.ui.getDom("elementpath").innerHTML =
  44. '<div class="edui-editor-breadcrumb">' +
  45. editor.getLang("elementPathTip") +
  46. ":</div>";
  47. }
  48. if (editor.options.wordCount) {
  49. function countFn() {
  50. setCount(editor, me);
  51. domUtils.un(editor.document, "click", arguments.callee);
  52. }
  53. domUtils.on(editor.document, "click", countFn);
  54. editor.ui.getDom("wordcount").innerHTML = editor.getLang(
  55. "wordCountTip"
  56. );
  57. }
  58. editor.ui._scale();
  59. if (editor.options.scaleEnabled) {
  60. if (editor.autoHeightEnabled) {
  61. editor.disableAutoHeight();
  62. }
  63. me.enableScale();
  64. } else {
  65. me.disableScale();
  66. }
  67. if (
  68. !editor.options.elementPathEnabled &&
  69. !editor.options.wordCount &&
  70. !editor.options.scaleEnabled
  71. ) {
  72. editor.ui.getDom("elementpath").style.display = "none";
  73. editor.ui.getDom("wordcount").style.display = "none";
  74. editor.ui.getDom("scale").style.display = "none";
  75. }
  76. if (!editor.selection.isFocus()) return;
  77. editor.fireEvent("selectionchange", false, true);
  78. });
  79. editor.addListener("mousedown", function(t, evt) {
  80. var el = evt.target || evt.srcElement;
  81. baidu.editor.ui.Popup.postHide(evt, el);
  82. baidu.editor.ui.ShortCutMenu.postHide(evt);
  83. });
  84. editor.addListener("delcells", function() {
  85. if (UE.ui["edittip"]) {
  86. new UE.ui["edittip"](editor);
  87. }
  88. editor.getDialog("edittip").open();
  89. });
  90. var pastePop,
  91. isPaste = false,
  92. timer;
  93. editor.addListener("afterpaste", function() {
  94. if (editor.queryCommandState("pasteplain")) return;
  95. if (baidu.editor.ui.PastePicker) {
  96. pastePop = new baidu.editor.ui.Popup({
  97. content: new baidu.editor.ui.PastePicker({ editor: editor }),
  98. editor: editor,
  99. className: "edui-wordpastepop"
  100. });
  101. pastePop.render();
  102. }
  103. isPaste = true;
  104. });
  105. editor.addListener("afterinserthtml", function() {
  106. clearTimeout(timer);
  107. timer = setTimeout(function() {
  108. if (pastePop && (isPaste || editor.ui._isTransfer)) {
  109. if (pastePop.isHidden()) {
  110. var span = domUtils.createElement(editor.document, "span", {
  111. style: "line-height:0px;",
  112. innerHTML: "\ufeff"
  113. }),
  114. range = editor.selection.getRange();
  115. range.insertNode(span);
  116. var tmp = getDomNode(span, "firstChild", "previousSibling");
  117. tmp &&
  118. pastePop.showAnchor(tmp.nodeType == 3 ? tmp.parentNode : tmp);
  119. domUtils.remove(span);
  120. } else {
  121. pastePop.show();
  122. }
  123. delete editor.ui._isTransfer;
  124. isPaste = false;
  125. }
  126. }, 200);
  127. });
  128. editor.addListener("contextmenu", function(t, evt) {
  129. baidu.editor.ui.Popup.postHide(evt);
  130. });
  131. editor.addListener("keydown", function(t, evt) {
  132. if (pastePop) pastePop.dispose(evt);
  133. var keyCode = evt.keyCode || evt.which;
  134. if (evt.altKey && keyCode == 90) {
  135. UE.ui.buttons["fullscreen"].onclick();
  136. }
  137. });
  138. editor.addListener("wordcount", function(type) {
  139. setCount(this, me);
  140. });
  141. function setCount(editor, ui) {
  142. editor.setOpt({
  143. wordCount: true,
  144. maximumWords: 10000,
  145. wordCountMsg:
  146. editor.options.wordCountMsg || editor.getLang("wordCountMsg"),
  147. wordOverFlowMsg:
  148. editor.options.wordOverFlowMsg || editor.getLang("wordOverFlowMsg")
  149. });
  150. var opt = editor.options,
  151. max = opt.maximumWords,
  152. msg = opt.wordCountMsg,
  153. errMsg = opt.wordOverFlowMsg,
  154. countDom = ui.getDom("wordcount");
  155. if (!opt.wordCount) {
  156. return;
  157. }
  158. var count = editor.getContentLength(true);
  159. if (count > max) {
  160. countDom.innerHTML = errMsg;
  161. editor.fireEvent("wordcountoverflow");
  162. } else {
  163. countDom.innerHTML = msg
  164. .replace("{#leave}", max - count)
  165. .replace("{#count}", count);
  166. }
  167. }
  168. editor.addListener("selectionchange", function() {
  169. if (editor.options.elementPathEnabled) {
  170. me[
  171. (editor.queryCommandState("elementpath") == -1 ? "dis" : "en") +
  172. "ableElementPath"
  173. ]();
  174. }
  175. if (editor.options.scaleEnabled) {
  176. me[
  177. (editor.queryCommandState("scale") == -1 ? "dis" : "en") +
  178. "ableScale"
  179. ]();
  180. }
  181. });
  182. var popup = new baidu.editor.ui.Popup({
  183. editor: editor,
  184. content: "",
  185. className: "edui-bubble",
  186. _onEditButtonClick: function() {
  187. this.hide();
  188. editor.ui._dialogs.linkDialog.open();
  189. },
  190. _onImgEditButtonClick: function(name) {
  191. this.hide();
  192. editor.ui._dialogs[name] && editor.ui._dialogs[name].open();
  193. },
  194. _onImgSetFloat: function(value) {
  195. this.hide();
  196. editor.execCommand("imagefloat", value);
  197. },
  198. _setIframeAlign: function(value) {
  199. var frame = popup.anchorEl;
  200. var newFrame = frame.cloneNode(true);
  201. switch (value) {
  202. case -2:
  203. newFrame.setAttribute("align", "");
  204. break;
  205. case -1:
  206. newFrame.setAttribute("align", "left");
  207. break;
  208. case 1:
  209. newFrame.setAttribute("align", "right");
  210. break;
  211. }
  212. frame.parentNode.insertBefore(newFrame, frame);
  213. domUtils.remove(frame);
  214. popup.anchorEl = newFrame;
  215. popup.showAnchor(popup.anchorEl);
  216. },
  217. _updateIframe: function() {
  218. var frame = (editor._iframe = popup.anchorEl);
  219. if (domUtils.hasClass(frame, "ueditor_baidumap")) {
  220. editor.selection.getRange().selectNode(frame).select();
  221. editor.ui._dialogs.mapDialog.open();
  222. popup.hide();
  223. } else {
  224. editor.ui._dialogs.insertframeDialog.open();
  225. popup.hide();
  226. }
  227. },
  228. _onRemoveButtonClick: function(cmdName) {
  229. editor.execCommand(cmdName);
  230. this.hide();
  231. },
  232. queryAutoHide: function(el) {
  233. if (el && el.ownerDocument == editor.document) {
  234. if (
  235. el.tagName.toLowerCase() == "img" ||
  236. domUtils.findParentByTagName(el, "a", true)
  237. ) {
  238. return el !== popup.anchorEl;
  239. }
  240. }
  241. return baidu.editor.ui.Popup.prototype.queryAutoHide.call(this, el);
  242. }
  243. });
  244. popup.render();
  245. if (editor.options.imagePopup) {
  246. editor.addListener("mouseover", function(t, evt) {
  247. evt = evt || window.event;
  248. var el = evt.target || evt.srcElement;
  249. if (
  250. editor.ui._dialogs.insertframeDialog &&
  251. /iframe/gi.test(el.tagName)
  252. ) {
  253. var html = popup.formatHtml(
  254. "<nobr>" +
  255. editor.getLang("property") +
  256. ': <span onclick=$$._setIframeAlign(-2) class="edui-clickable">' +
  257. editor.getLang("default") +
  258. '</span>&nbsp;&nbsp;<span onclick=$$._setIframeAlign(-1) class="edui-clickable">' +
  259. editor.getLang("justifyleft") +
  260. '</span>&nbsp;&nbsp;<span onclick=$$._setIframeAlign(1) class="edui-clickable">' +
  261. editor.getLang("justifyright") +
  262. "</span>&nbsp;&nbsp;" +
  263. ' <span onclick="$$._updateIframe( this);" class="edui-clickable">' +
  264. editor.getLang("modify") +
  265. "</span></nobr>"
  266. );
  267. if (html) {
  268. popup.getDom("content").innerHTML = html;
  269. popup.anchorEl = el;
  270. popup.showAnchor(popup.anchorEl);
  271. } else {
  272. popup.hide();
  273. }
  274. }
  275. });
  276. editor.addListener("selectionchange", function(t, causeByUi) {
  277. if (!causeByUi) return;
  278. var html = "",
  279. str = "",
  280. img = editor.selection.getRange().getClosedNode(),
  281. dialogs = editor.ui._dialogs;
  282. if (img && img.tagName == "IMG") {
  283. var dialogName = "insertimageDialog";
  284. if (
  285. img.className.indexOf("edui-faked-video") != -1 ||
  286. img.className.indexOf("edui-upload-video") != -1
  287. ) {
  288. dialogName = "insertvideoDialog";
  289. }
  290. if (img.className.indexOf("edui-faked-webapp") != -1) {
  291. dialogName = "webappDialog";
  292. }
  293. if (img.src.indexOf("http://api.map.baidu.com") != -1) {
  294. dialogName = "mapDialog";
  295. }
  296. if (img.className.indexOf("edui-faked-music") != -1) {
  297. dialogName = "musicDialog";
  298. }
  299. if (
  300. img.src.indexOf("http://maps.google.com/maps/api/staticmap") != -1
  301. ) {
  302. dialogName = "gmapDialog";
  303. }
  304. if (img.getAttribute("anchorname")) {
  305. dialogName = "anchorDialog";
  306. html = popup.formatHtml(
  307. "<nobr>" +
  308. editor.getLang("property") +
  309. ': <span onclick=$$._onImgEditButtonClick("anchorDialog") class="edui-clickable">' +
  310. editor.getLang("modify") +
  311. "</span>&nbsp;&nbsp;" +
  312. "<span onclick=$$._onRemoveButtonClick('anchor') class=\"edui-clickable\">" +
  313. editor.getLang("delete") +
  314. "</span></nobr>"
  315. );
  316. }
  317. if (img.getAttribute("word_img")) {
  318. //todo 放到dialog去做查询
  319. editor.word_img = [img.getAttribute("word_img")];
  320. dialogName = "wordimageDialog";
  321. }
  322. if (
  323. domUtils.hasClass(img, "loadingclass") ||
  324. domUtils.hasClass(img, "loaderrorclass")
  325. ) {
  326. dialogName = "";
  327. }
  328. if (!dialogs[dialogName]) {
  329. return;
  330. }
  331. str =
  332. "<nobr>" +
  333. editor.getLang("property") +
  334. ": " +
  335. '<span onclick=$$._onImgSetFloat("none") class="edui-clickable">' +
  336. editor.getLang("default") +
  337. "</span>&nbsp;&nbsp;" +
  338. '<span onclick=$$._onImgSetFloat("left") class="edui-clickable">' +
  339. editor.getLang("justifyleft") +
  340. "</span>&nbsp;&nbsp;" +
  341. '<span onclick=$$._onImgSetFloat("right") class="edui-clickable">' +
  342. editor.getLang("justifyright") +
  343. "</span>&nbsp;&nbsp;" +
  344. '<span onclick=$$._onImgSetFloat("center") class="edui-clickable">' +
  345. editor.getLang("justifycenter") +
  346. "</span>&nbsp;&nbsp;" +
  347. "<span onclick=\"$$._onImgEditButtonClick('" +
  348. dialogName +
  349. '\');" class="edui-clickable">' +
  350. editor.getLang("modify") +
  351. "</span></nobr>";
  352. !html && (html = popup.formatHtml(str));
  353. }
  354. if (editor.ui._dialogs.linkDialog) {
  355. var link = editor.queryCommandValue("link");
  356. var url;
  357. if (
  358. link &&
  359. (url = link.getAttribute("_href") || link.getAttribute("href", 2))
  360. ) {
  361. var txt = url;
  362. if (url.length > 30) {
  363. txt = url.substring(0, 20) + "...";
  364. }
  365. if (html) {
  366. html += '<div style="height:5px;"></div>';
  367. }
  368. html += popup.formatHtml(
  369. "<nobr>" +
  370. editor.getLang("anthorMsg") +
  371. ': <a target="_blank" href="' +
  372. url +
  373. '" title="' +
  374. url +
  375. '" >' +
  376. txt +
  377. "</a>" +
  378. ' <span class="edui-clickable" onclick="$$._onEditButtonClick();">' +
  379. editor.getLang("modify") +
  380. "</span>" +
  381. ' <span class="edui-clickable" onclick="$$._onRemoveButtonClick(\'unlink\');"> ' +
  382. editor.getLang("clear") +
  383. "</span></nobr>"
  384. );
  385. popup.showAnchor(link);
  386. }
  387. }
  388. if (html) {
  389. popup.getDom("content").innerHTML = html;
  390. popup.anchorEl = img || link;
  391. popup.showAnchor(popup.anchorEl);
  392. } else {
  393. popup.hide();
  394. }
  395. });
  396. }
  397. },
  398. _initToolbars: function() {
  399. var editor = this.editor;
  400. var toolbars = this.toolbars || [];
  401. var toolbarUis = [];
  402. var extraUIs = [];
  403. for (var i = 0; i < toolbars.length; i++) {
  404. var toolbar = toolbars[i];
  405. var toolbarUi = new baidu.editor.ui.Toolbar({
  406. theme: editor.options.theme
  407. });
  408. for (var j = 0; j < toolbar.length; j++) {
  409. var toolbarItem = toolbar[j];
  410. var toolbarItemUi = null;
  411. if (typeof toolbarItem == "string") {
  412. toolbarItem = toolbarItem.toLowerCase();
  413. if (toolbarItem == "|") {
  414. toolbarItem = "Separator";
  415. }
  416. if (toolbarItem == "||") {
  417. toolbarItem = "Breakline";
  418. }
  419. var ui = baidu.editor.ui[toolbarItem];
  420. if (ui) {
  421. if (utils.isFunction(ui)) {
  422. toolbarItemUi = new baidu.editor.ui[toolbarItem](editor);
  423. } else {
  424. if (ui.id && ui.id != editor.key) {
  425. continue;
  426. }
  427. var itemUI = ui.execFn.call(editor, editor, toolbarItem);
  428. if (itemUI) {
  429. if (ui.index === undefined) {
  430. toolbarUi.add(itemUI);
  431. continue;
  432. } else {
  433. extraUIs.push({
  434. index: ui.index,
  435. itemUI: itemUI
  436. });
  437. }
  438. }
  439. }
  440. }
  441. //fullscreen这里单独处理一下,放到首行去
  442. if (toolbarItem == "fullscreen") {
  443. if (toolbarUis && toolbarUis[0]) {
  444. toolbarUis[0].items.splice(0, 0, toolbarItemUi);
  445. } else {
  446. toolbarItemUi && toolbarUi.items.splice(0, 0, toolbarItemUi);
  447. }
  448. continue;
  449. }
  450. } else {
  451. toolbarItemUi = toolbarItem;
  452. }
  453. if (toolbarItemUi && toolbarItemUi.id) {
  454. toolbarUi.add(toolbarItemUi);
  455. }
  456. }
  457. toolbarUis[i] = toolbarUi;
  458. }
  459. //接受外部定制的UI
  460. utils.each(extraUIs, function(obj) {
  461. toolbarUi.add(obj.itemUI, obj.index);
  462. });
  463. this.toolbars = toolbarUis;
  464. },
  465. getHtmlTpl: function() {
  466. return (
  467. '<div id="##" class="%%">' +
  468. '<div id="##_toolbarbox" class="%%-toolbarbox">' +
  469. (this.toolbars.length
  470. ? '<div id="##_toolbarboxouter" class="%%-toolbarboxouter"><div class="%%-toolbarboxinner">' +
  471. this.renderToolbarBoxHtml() +
  472. "</div></div>"
  473. : "") +
  474. '<div id="##_toolbarmsg" class="%%-toolbarmsg" style="display:none;">' +
  475. '<div id = "##_upload_dialog" class="%%-toolbarmsg-upload" onclick="$$.showWordImageDialog();">' +
  476. this.editor.getLang("clickToUpload") +
  477. "</div>" +
  478. '<div class="%%-toolbarmsg-close" onclick="$$.hideToolbarMsg();">x</div>' +
  479. '<div id="##_toolbarmsg_label" class="%%-toolbarmsg-label"></div>' +
  480. '<div style="height:0;overflow:hidden;clear:both;"></div>' +
  481. "</div>" +
  482. '<div id="##_message_holder" class="%%-messageholder"></div>' +
  483. "</div>" +
  484. '<div id="##_iframeholder" class="%%-iframeholder">' +
  485. "</div>" +
  486. //modify wdcount by matao
  487. '<div id="##_bottombar" class="%%-bottomContainer"><table><tr>' +
  488. '<td id="##_elementpath" class="%%-bottombar"></td>' +
  489. '<td id="##_wordcount" class="%%-wordcount"></td>' +
  490. '<td id="##_scale" class="%%-scale"><div class="%%-icon"></div></td>' +
  491. "</tr></table></div>" +
  492. '<div id="##_scalelayer"></div>' +
  493. "</div>"
  494. );
  495. },
  496. showWordImageDialog: function() {
  497. this._dialogs["wordimageDialog"].open();
  498. },
  499. renderToolbarBoxHtml: function() {
  500. var buff = [];
  501. for (var i = 0; i < this.toolbars.length; i++) {
  502. buff.push(this.toolbars[i].renderHtml());
  503. }
  504. return buff.join("");
  505. },
  506. setFullScreen: function(fullscreen) {
  507. var editor = this.editor,
  508. container = editor.container.parentNode.parentNode;
  509. if (this._fullscreen != fullscreen) {
  510. this._fullscreen = fullscreen;
  511. this.editor.fireEvent("beforefullscreenchange", fullscreen);
  512. if (baidu.editor.browser.gecko) {
  513. var bk = editor.selection.getRange().createBookmark();
  514. }
  515. if (fullscreen) {
  516. while (container.tagName != "BODY") {
  517. var position = baidu.editor.dom.domUtils.getComputedStyle(
  518. container,
  519. "position"
  520. );
  521. nodeStack.push(position);
  522. container.style.position = "static";
  523. container = container.parentNode;
  524. }
  525. this._bakHtmlOverflow = document.documentElement.style.overflow;
  526. this._bakBodyOverflow = document.body.style.overflow;
  527. this._bakAutoHeight = this.editor.autoHeightEnabled;
  528. this._bakScrollTop = Math.max(
  529. document.documentElement.scrollTop,
  530. document.body.scrollTop
  531. );
  532. this._bakEditorContaninerWidth = editor.iframe.parentNode.offsetWidth;
  533. if (this._bakAutoHeight) {
  534. //当全屏时不能执行自动长高
  535. editor.autoHeightEnabled = false;
  536. this.editor.disableAutoHeight();
  537. }
  538. document.documentElement.style.overflow = "hidden";
  539. //修复,滚动条不收起的问题
  540. window.scrollTo(0, window.scrollY);
  541. this._bakCssText = this.getDom().style.cssText;
  542. this._bakCssText1 = this.getDom("iframeholder").style.cssText;
  543. editor.iframe.parentNode.style.width = "";
  544. this._updateFullScreen();
  545. } else {
  546. while (container.tagName != "BODY") {
  547. container.style.position = nodeStack.shift();
  548. container = container.parentNode;
  549. }
  550. this.getDom().style.cssText = this._bakCssText;
  551. this.getDom("iframeholder").style.cssText = this._bakCssText1;
  552. if (this._bakAutoHeight) {
  553. editor.autoHeightEnabled = true;
  554. this.editor.enableAutoHeight();
  555. }
  556. document.documentElement.style.overflow = this._bakHtmlOverflow;
  557. document.body.style.overflow = this._bakBodyOverflow;
  558. editor.iframe.parentNode.style.width =
  559. this._bakEditorContaninerWidth + "px";
  560. window.scrollTo(0, this._bakScrollTop);
  561. }
  562. if (browser.gecko && editor.body.contentEditable === "true") {
  563. var input = document.createElement("input");
  564. document.body.appendChild(input);
  565. editor.body.contentEditable = false;
  566. setTimeout(function() {
  567. input.focus();
  568. setTimeout(function() {
  569. editor.body.contentEditable = true;
  570. editor.fireEvent("fullscreenchanged", fullscreen);
  571. editor.selection.getRange().moveToBookmark(bk).select(true);
  572. baidu.editor.dom.domUtils.remove(input);
  573. fullscreen && window.scroll(0, 0);
  574. }, 0);
  575. }, 0);
  576. }
  577. if (editor.body.contentEditable === "true") {
  578. this.editor.fireEvent("fullscreenchanged", fullscreen);
  579. this.triggerLayout();
  580. }
  581. }
  582. },
  583. _updateFullScreen: function() {
  584. if (this._fullscreen) {
  585. var vpRect = uiUtils.getViewportRect();
  586. this.getDom().style.cssText =
  587. "border:0;position:absolute;left:0;top:" +
  588. (this.editor.options.topOffset || 0) +
  589. "px;width:" +
  590. vpRect.width +
  591. "px;height:" +
  592. vpRect.height +
  593. "px;z-index:" +
  594. (this.getDom().style.zIndex * 1 + 100);
  595. uiUtils.setViewportOffset(this.getDom(), {
  596. left: 0,
  597. top: this.editor.options.topOffset || 0
  598. });
  599. this.editor.setHeight(
  600. vpRect.height -
  601. this.getDom("toolbarbox").offsetHeight -
  602. this.getDom("bottombar").offsetHeight -
  603. (this.editor.options.topOffset || 0),
  604. true
  605. );
  606. //不手动调一下,会导致全屏失效
  607. if (browser.gecko) {
  608. try {
  609. window.onresize();
  610. } catch (e) {}
  611. }
  612. }
  613. },
  614. _updateElementPath: function() {
  615. var bottom = this.getDom("elementpath"),
  616. list;
  617. if (
  618. this.elementPathEnabled &&
  619. (list = this.editor.queryCommandValue("elementpath"))
  620. ) {
  621. var buff = [];
  622. for (var i = 0, ci; (ci = list[i]); i++) {
  623. buff[i] = this.formatHtml(
  624. '<span unselectable="on" onclick="$$.editor.execCommand(&quot;elementpath&quot;, &quot;' +
  625. i +
  626. '&quot;);">' +
  627. ci +
  628. "</span>"
  629. );
  630. }
  631. bottom.innerHTML =
  632. '<div class="edui-editor-breadcrumb" onmousedown="return false;">' +
  633. this.editor.getLang("elementPathTip") +
  634. ": " +
  635. buff.join(" &gt; ") +
  636. "</div>";
  637. } else {
  638. bottom.style.display = "none";
  639. }
  640. },
  641. disableElementPath: function() {
  642. var bottom = this.getDom("elementpath");
  643. bottom.innerHTML = "";
  644. bottom.style.display = "none";
  645. this.elementPathEnabled = false;
  646. },
  647. enableElementPath: function() {
  648. var bottom = this.getDom("elementpath");
  649. bottom.style.display = "";
  650. this.elementPathEnabled = true;
  651. this._updateElementPath();
  652. },
  653. _scale: function() {
  654. var doc = document,
  655. editor = this.editor,
  656. editorHolder = editor.container,
  657. editorDocument = editor.document,
  658. toolbarBox = this.getDom("toolbarbox"),
  659. bottombar = this.getDom("bottombar"),
  660. scale = this.getDom("scale"),
  661. scalelayer = this.getDom("scalelayer");
  662. var isMouseMove = false,
  663. position = null,
  664. minEditorHeight = 0,
  665. minEditorWidth = editor.options.minFrameWidth,
  666. pageX = 0,
  667. pageY = 0,
  668. scaleWidth = 0,
  669. scaleHeight = 0;
  670. function down() {
  671. position = domUtils.getXY(editorHolder);
  672. if (!minEditorHeight) {
  673. minEditorHeight =
  674. editor.options.minFrameHeight +
  675. toolbarBox.offsetHeight +
  676. bottombar.offsetHeight;
  677. }
  678. scalelayer.style.cssText =
  679. "position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:" +
  680. editorHolder.offsetWidth +
  681. "px;height:" +
  682. editorHolder.offsetHeight +
  683. "px;z-index:" +
  684. (editor.options.zIndex + 1);
  685. domUtils.on(doc, "mousemove", move);
  686. domUtils.on(editorDocument, "mouseup", up);
  687. domUtils.on(doc, "mouseup", up);
  688. }
  689. var me = this;
  690. //by xuheng 全屏时关掉缩放
  691. this.editor.addListener("fullscreenchanged", function(e, fullScreen) {
  692. if (fullScreen) {
  693. me.disableScale();
  694. } else {
  695. if (me.editor.options.scaleEnabled) {
  696. me.enableScale();
  697. var tmpNode = me.editor.document.createElement("span");
  698. me.editor.body.appendChild(tmpNode);
  699. me.editor.body.style.height =
  700. Math.max(
  701. domUtils.getXY(tmpNode).y,
  702. me.editor.iframe.offsetHeight - 20
  703. ) + "px";
  704. domUtils.remove(tmpNode);
  705. }
  706. }
  707. });
  708. function move(event) {
  709. clearSelection();
  710. var e = event || window.event;
  711. pageX = e.pageX || doc.documentElement.scrollLeft + e.clientX;
  712. pageY = e.pageY || doc.documentElement.scrollTop + e.clientY;
  713. scaleWidth = pageX - position.x;
  714. scaleHeight = pageY - position.y;
  715. if (scaleWidth >= minEditorWidth) {
  716. isMouseMove = true;
  717. scalelayer.style.width = scaleWidth + "px";
  718. }
  719. if (scaleHeight >= minEditorHeight) {
  720. isMouseMove = true;
  721. scalelayer.style.height = scaleHeight + "px";
  722. }
  723. }
  724. function up() {
  725. if (isMouseMove) {
  726. isMouseMove = false;
  727. editor.ui._actualFrameWidth = scalelayer.offsetWidth - 2;
  728. editorHolder.style.width = editor.ui._actualFrameWidth + "px";
  729. editor.setHeight(
  730. scalelayer.offsetHeight -
  731. bottombar.offsetHeight -
  732. toolbarBox.offsetHeight -
  733. 2,
  734. true
  735. );
  736. }
  737. if (scalelayer) {
  738. scalelayer.style.display = "none";
  739. }
  740. clearSelection();
  741. domUtils.un(doc, "mousemove", move);
  742. domUtils.un(editorDocument, "mouseup", up);
  743. domUtils.un(doc, "mouseup", up);
  744. }
  745. function clearSelection() {
  746. if (browser.ie) doc.selection.clear();
  747. else window.getSelection().removeAllRanges();
  748. }
  749. this.enableScale = function() {
  750. //trace:2868
  751. if (editor.queryCommandState("source") == 1) return;
  752. scale.style.display = "";
  753. this.scaleEnabled = true;
  754. domUtils.on(scale, "mousedown", down);
  755. };
  756. this.disableScale = function() {
  757. scale.style.display = "none";
  758. this.scaleEnabled = false;
  759. domUtils.un(scale, "mousedown", down);
  760. };
  761. },
  762. isFullScreen: function() {
  763. return this._fullscreen;
  764. },
  765. postRender: function() {
  766. UIBase.prototype.postRender.call(this);
  767. for (var i = 0; i < this.toolbars.length; i++) {
  768. this.toolbars[i].postRender();
  769. }
  770. var me = this;
  771. var timerId,
  772. domUtils = baidu.editor.dom.domUtils,
  773. updateFullScreenTime = function() {
  774. clearTimeout(timerId);
  775. timerId = setTimeout(function() {
  776. me._updateFullScreen();
  777. });
  778. };
  779. domUtils.on(window, "resize", updateFullScreenTime);
  780. me.addListener("destroy", function() {
  781. domUtils.un(window, "resize", updateFullScreenTime);
  782. clearTimeout(timerId);
  783. });
  784. },
  785. showToolbarMsg: function(msg, flag) {
  786. this.getDom("toolbarmsg_label").innerHTML = msg;
  787. this.getDom("toolbarmsg").style.display = "";
  788. //
  789. if (!flag) {
  790. var w = this.getDom("upload_dialog");
  791. w.style.display = "none";
  792. }
  793. },
  794. hideToolbarMsg: function() {
  795. this.getDom("toolbarmsg").style.display = "none";
  796. },
  797. mapUrl: function(url) {
  798. return url
  799. ? url.replace("~/", this.editor.options.UEDITOR_HOME_URL || "")
  800. : "";
  801. },
  802. triggerLayout: function() {
  803. var dom = this.getDom();
  804. if (dom.style.zoom == "1") {
  805. dom.style.zoom = "100%";
  806. } else {
  807. dom.style.zoom = "1";
  808. }
  809. }
  810. };
  811. utils.inherits(EditorUI, baidu.editor.ui.UIBase);
  812. var instances = {};
  813. UE.ui.Editor = function(options) {
  814. var editor = new UE.Editor(options);
  815. editor.options.editor = editor;
  816. utils.loadFile(document, {
  817. href:
  818. editor.options.themePath + editor.options.theme + "/_css/ueditor.css",
  819. tag: "link",
  820. type: "text/css",
  821. rel: "stylesheet"
  822. });
  823. var oldRender = editor.render;
  824. editor.render = function(holder) {
  825. if (holder.constructor === String) {
  826. editor.key = holder;
  827. instances[holder] = editor;
  828. }
  829. utils.domReady(function() {
  830. editor.langIsReady
  831. ? renderUI()
  832. : editor.addListener("langReady", renderUI);
  833. function renderUI() {
  834. editor.setOpt({
  835. labelMap: editor.options.labelMap || editor.getLang("labelMap")
  836. });
  837. new EditorUI(editor.options);
  838. if (holder) {
  839. if (holder.constructor === String) {
  840. holder = document.getElementById(holder);
  841. }
  842. holder &&
  843. holder.getAttribute("name") &&
  844. (editor.options.textarea = holder.getAttribute("name"));
  845. if (holder && /script|textarea/gi.test(holder.tagName)) {
  846. var newDiv = document.createElement("div");
  847. holder.parentNode.insertBefore(newDiv, holder);
  848. var cont = holder.value || holder.innerHTML;
  849. editor.options.initialContent = /^[\t\r\n ]*$/.test(cont)
  850. ? editor.options.initialContent
  851. : cont
  852. .replace(/>[\n\r\t]+([ ]{4})+/g, ">")
  853. .replace(/[\n\r\t]+([ ]{4})+</g, "<")
  854. .replace(/>[\n\r\t]+</g, "><");
  855. holder.className && (newDiv.className = holder.className);
  856. holder.style.cssText &&
  857. (newDiv.style.cssText = holder.style.cssText);
  858. if (/textarea/i.test(holder.tagName)) {
  859. editor.textarea = holder;
  860. editor.textarea.style.display = "none";
  861. } else {
  862. holder.parentNode.removeChild(holder);
  863. }
  864. if (holder.id) {
  865. newDiv.id = holder.id;
  866. domUtils.removeAttributes(holder, "id");
  867. }
  868. holder = newDiv;
  869. holder.innerHTML = "";
  870. }
  871. }
  872. domUtils.addClass(holder, "edui-" + editor.options.theme);
  873. editor.ui.render(holder);
  874. var opt = editor.options;
  875. //给实例添加一个编辑器的容器引用
  876. editor.container = editor.ui.getDom();
  877. var parents = domUtils.findParents(holder, true);
  878. var displays = [];
  879. for (var i = 0, ci; (ci = parents[i]); i++) {
  880. displays[i] = ci.style.display;
  881. ci.style.display = "block";
  882. }
  883. if (opt.initialFrameWidth) {
  884. opt.minFrameWidth = opt.initialFrameWidth;
  885. } else {
  886. opt.minFrameWidth = opt.initialFrameWidth = holder.offsetWidth;
  887. var styleWidth = holder.style.width;
  888. if (/%$/.test(styleWidth)) {
  889. opt.initialFrameWidth = styleWidth;
  890. }
  891. }
  892. if (opt.initialFrameHeight) {
  893. opt.minFrameHeight = opt.initialFrameHeight;
  894. } else {
  895. opt.initialFrameHeight = opt.minFrameHeight = holder.offsetHeight;
  896. }
  897. for (var i = 0, ci; (ci = parents[i]); i++) {
  898. ci.style.display = displays[i];
  899. }
  900. //编辑器最外容器设置了高度,会导致,编辑器不占位
  901. //todo 先去掉,没有找到原因
  902. if (holder.style.height) {
  903. holder.style.height = "";
  904. }
  905. editor.container.style.width =
  906. opt.initialFrameWidth +
  907. (/%$/.test(opt.initialFrameWidth) ? "" : "px");
  908. editor.container.style.zIndex = opt.zIndex;
  909. oldRender.call(editor, editor.ui.getDom("iframeholder"));
  910. editor.fireEvent("afteruiready");
  911. }
  912. });
  913. };
  914. return editor;
  915. };
  916. /**
  917. * @file
  918. * @name UE
  919. * @short UE
  920. * @desc UEditor的顶部命名空间
  921. */
  922. /**
  923. * @name getEditor
  924. * @since 1.2.4+
  925. * @grammar UE.getEditor(id,[opt]) => Editor实例
  926. * @desc 提供一个全局的方法得到编辑器实例
  927. *
  928. * * ''id'' 放置编辑器的容器id, 如果容器下的编辑器已经存在,就直接返回
  929. * * ''opt'' 编辑器的可选参数
  930. * @example
  931. * UE.getEditor('containerId',{onready:function(){//创建一个编辑器实例
  932. * this.setContent('hello')
  933. * }});
  934. * UE.getEditor('containerId'); //返回刚创建的实例
  935. *
  936. */
  937. UE.getEditor = function(id, opt) {
  938. var editor = instances[id];
  939. if (!editor) {
  940. editor = instances[id] = new UE.ui.Editor(opt);
  941. editor.render(id);
  942. }
  943. return editor;
  944. };
  945. UE.delEditor = function(id) {
  946. var editor;
  947. if ((editor = instances[id])) {
  948. editor.key && editor.destroy();
  949. delete instances[id];
  950. }
  951. };
  952. UE.registerUI = function(uiName, fn, index, editorId) {
  953. utils.each(uiName.split(/\s+/), function(name) {
  954. baidu.editor.ui[name] = {
  955. id: editorId,
  956. execFn: fn,
  957. index: index
  958. };
  959. });
  960. };
  961. })();