Dialogs.js 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976
  1. /**
  2. * Copyright (c) 2006-2012, JGraph Ltd
  3. */
  4. /**
  5. * Constructs a new open dialog.
  6. */
  7. var OpenDialog = function()
  8. {
  9. var iframe = document.createElement('iframe');
  10. iframe.style.backgroundColor = 'transparent';
  11. iframe.allowTransparency = 'true';
  12. iframe.style.borderStyle = 'none';
  13. iframe.style.borderWidth = '0px';
  14. iframe.style.overflow = 'hidden';
  15. iframe.style.maxWidth = '100%';
  16. iframe.frameBorder = '0';
  17. var dx = 0;
  18. iframe.setAttribute('width', (((Editor.useLocalStorage) ? 640 : 320) + dx) + 'px');
  19. iframe.setAttribute('height', (((Editor.useLocalStorage) ? 480 : 220) + dx) + 'px');
  20. iframe.setAttribute('src', OPEN_FORM);
  21. this.container = iframe;
  22. };
  23. /**
  24. * Constructs a new color dialog.
  25. */
  26. var ColorDialog = function(editorUi, color, apply, cancelFn, defaultColor, defaultColorValue)
  27. {
  28. this.editorUi = editorUi;
  29. var input = document.createElement('input');
  30. input.style.marginBottom = '10px';
  31. input.style.marginLeft = '8px';
  32. // Required for picker to render in IE
  33. if (mxClient.IS_IE)
  34. {
  35. input.style.marginTop = '10px';
  36. document.body.appendChild(input);
  37. }
  38. var applyFunction = (apply != null) ? apply :
  39. this.createApplyFunction();
  40. if (defaultColorValue == null)
  41. {
  42. defaultColorValue = (Editor.isDarkMode() &&
  43. defaultColor == 'default') ?
  44. '#ffffff' : '#000000';
  45. }
  46. var defaultColorLabel = defaultColorValue.substring(1).toUpperCase() +
  47. ' (' + mxResources.get('automatic') + ')';
  48. function validateColorName(value, resolveDefault, defaultTextValue)
  49. {
  50. var color = value;
  51. var lc = color.toLowerCase();
  52. // Resolves special names for default color value
  53. if (defaultColor != null &&
  54. (color == '' || lc == 'automatic' ||
  55. lc == defaultColorLabel.toLowerCase() ||
  56. lc == mxResources.get('default').toLowerCase()) ||
  57. lc == mxResources.get('automatic').toLowerCase())
  58. {
  59. color = 'default';
  60. }
  61. if (lc == mxResources.get('none').toLowerCase())
  62. {
  63. color = 'none';
  64. }
  65. if (defaultColor != null && color == 'default')
  66. {
  67. if (resolveDefault)
  68. {
  69. color = defaultColorValue;
  70. }
  71. else if (defaultTextValue != null)
  72. {
  73. color = defaultTextValue;
  74. }
  75. }
  76. else if (color != 'none' && color.charAt(0) != '#')
  77. {
  78. try
  79. {
  80. // Resolves color names
  81. var ctx = document.createElement("canvas").getContext("2d");
  82. // Check if color is hex value
  83. ctx.fillStyle = '#' + color;
  84. if (ctx.fillStyle != '#' + color.toLowerCase())
  85. {
  86. ctx.fillStyle = color;
  87. color = ctx.fillStyle.substring(1).toUpperCase();
  88. }
  89. }
  90. catch (e)
  91. {
  92. // ignore
  93. }
  94. }
  95. return color;
  96. };
  97. function doApply()
  98. {
  99. var color = validateColorName(input.value, false);
  100. // Blocks any non-alphabetic chars in colors
  101. if (/(^#?[a-zA-Z0-9]*$)/.test(color))
  102. {
  103. if (color != 'default')
  104. {
  105. if (color != 'none' && color.charAt(0) != '#')
  106. {
  107. color = '#' + color;
  108. }
  109. ColorDialog.addRecentColor((color != 'none') ?
  110. color.substring(1) : color, 12);
  111. }
  112. applyFunction(color);
  113. editorUi.hideDialog();
  114. }
  115. else
  116. {
  117. editorUi.handleError({message: mxResources.get('invalidInput')});
  118. }
  119. };
  120. function selectInput()
  121. {
  122. if (!mxClient.IS_TOUCH)
  123. {
  124. input.focus();
  125. if (mxClient.IS_GC || mxClient.IS_FF || document.documentMode >= 5)
  126. {
  127. input.select();
  128. }
  129. else
  130. {
  131. document.execCommand('selectAll', false, null);
  132. }
  133. }
  134. };
  135. this.init = function()
  136. {
  137. selectInput();
  138. };
  139. var picker = new mxJSColor.color(input);
  140. picker.pickerOnfocus = false;
  141. picker.showPicker();
  142. var div = document.createElement('div');
  143. mxJSColor.picker.box.style.position = 'relative';
  144. mxJSColor.picker.box.style.width = '230px';
  145. mxJSColor.picker.box.style.height = '100px';
  146. mxJSColor.picker.box.style.paddingBottom = '10px';
  147. div.appendChild(mxJSColor.picker.box);
  148. var center = document.createElement('center');
  149. function createRecentColorTable()
  150. {
  151. var table = addPresets((ColorDialog.recentColors.length == 0) ?
  152. ['FFFFFF'] : ColorDialog.recentColors, 11, 'FFFFFF', true);
  153. table.style.marginBottom = '8px';
  154. return table;
  155. };
  156. var addPresets = mxUtils.bind(this, function(presets, rowLength, defaultColor, addResetOption)
  157. {
  158. rowLength = (rowLength != null) ? rowLength : 12;
  159. var table = document.createElement('table');
  160. table.style.borderCollapse = 'collapse';
  161. table.setAttribute('cellspacing', '0');
  162. table.style.marginBottom = '20px';
  163. table.style.cellSpacing = '0px';
  164. table.style.marginLeft = '1px';
  165. var tbody = document.createElement('tbody');
  166. table.appendChild(tbody);
  167. var rows = presets.length / rowLength;
  168. for (var row = 0; row < rows; row++)
  169. {
  170. var tr = document.createElement('tr');
  171. for (var i = 0; i < rowLength; i++)
  172. {
  173. (mxUtils.bind(this, function(clr)
  174. {
  175. var td = document.createElement('td');
  176. td.style.border = '0px solid black';
  177. td.style.padding = '0px';
  178. td.style.width = '16px';
  179. td.style.height = '16px';
  180. if (clr == null)
  181. {
  182. clr = defaultColor;
  183. }
  184. if (clr != null)
  185. {
  186. td.style.borderWidth = '1px';
  187. if (clr == 'none')
  188. {
  189. td.style.background = 'url(\'' + Dialog.prototype.noColorImage + '\')';
  190. }
  191. else
  192. {
  193. td.style.backgroundColor = '#' + clr;
  194. }
  195. var name = this.colorNames[String(clr).toUpperCase()];
  196. if (name != null)
  197. {
  198. td.setAttribute('title', name);
  199. }
  200. }
  201. tr.appendChild(td);
  202. if (clr != null)
  203. {
  204. td.style.cursor = 'pointer';
  205. mxEvent.addListener(td, 'click', function()
  206. {
  207. if (clr == 'none')
  208. {
  209. picker.fromString('ffffff');
  210. input.value = 'none';
  211. }
  212. else
  213. {
  214. picker.fromString(clr);
  215. }
  216. });
  217. mxEvent.addListener(td, 'dblclick', doApply);
  218. }
  219. }))(presets[row * rowLength + i]);
  220. }
  221. tbody.appendChild(tr);
  222. }
  223. if (addResetOption)
  224. {
  225. var td = document.createElement('td');
  226. td.setAttribute('title', mxResources.get('reset'));
  227. td.className = 'geAdaptiveAsset';
  228. td.style.border = '1px solid black';
  229. td.style.padding = '0px';
  230. td.style.width = '16px';
  231. td.style.height = '16px';
  232. td.style.backgroundImage = 'url(\'' + Editor.crossImage + '\')';
  233. td.style.backgroundPosition = 'center center';
  234. td.style.backgroundSize = '14px 14px';
  235. td.style.backgroundRepeat = 'no-repeat';
  236. td.style.cursor = 'pointer';
  237. tr.appendChild(td);
  238. mxEvent.addListener(td, 'click', function()
  239. {
  240. ColorDialog.resetRecentColors();
  241. table.parentNode.replaceChild(createRecentColorTable(), table);
  242. });
  243. }
  244. center.appendChild(table);
  245. return table;
  246. });
  247. var w = 216;
  248. div.appendChild(input);
  249. if (defaultColor != null)
  250. {
  251. w -= 34;
  252. var defaultBtn = mxUtils.button('', function()
  253. {
  254. picker.fromString(defaultColorValue);
  255. input.value = defaultColorLabel;
  256. });
  257. defaultBtn.setAttribute('title', mxResources.get('reset'));
  258. defaultBtn.style.cursor = 'pointer';
  259. defaultBtn.style.position = 'relative';
  260. defaultBtn.style.marginLeft = '4px';
  261. defaultBtn.innerText = '';
  262. var def = document.createElement('div');
  263. def.style.background = 'url(\'' + Dialog.prototype.defaultColorImage + '\')';
  264. def.style.backgroundPosition = 'center center';
  265. def.style.backgroundRepeat = 'no-repeat';
  266. def.style.display = 'inline-block';
  267. def.style.verticalAlign = 'middle';
  268. def.style.marginTop = '-2px';
  269. def.style.width = '12px';
  270. def.style.height = '12px';
  271. defaultBtn.appendChild(def);
  272. div.appendChild(defaultBtn);
  273. mxEvent.addListener(defaultBtn, 'dblclick', doApply);
  274. }
  275. if (!mxClient.IS_IE && !mxClient.IS_IE11)
  276. {
  277. w -= 34;
  278. var clrInput = document.createElement('input');
  279. clrInput.setAttribute('type', 'color');
  280. clrInput.style.position = 'relative';
  281. clrInput.style.visibility = 'hidden';
  282. clrInput.style.top = '10px';
  283. clrInput.style.width = '0px';
  284. clrInput.style.height = '0px';
  285. clrInput.style.border = 'none';
  286. div.style.whiteSpace = 'nowrap';
  287. div.appendChild(clrInput);
  288. var dropperBtn = mxUtils.button('', function()
  289. {
  290. // LATER: Check if clrInput is expanded
  291. if (document.activeElement == clrInput)
  292. {
  293. input.focus();
  294. }
  295. else
  296. {
  297. clrInput.value = '#' + input.value;
  298. clrInput.click();
  299. }
  300. });
  301. dropperBtn.style.cursor = 'pointer';
  302. var dropper = document.createElement('img');
  303. dropper.src = Editor.colorDropperImage;
  304. dropper.className = 'geAdaptiveAsset';
  305. dropper.style.position = 'relative';
  306. dropper.style.verticalAlign = 'middle';
  307. dropper.style.marginTop = '-2px';
  308. dropper.style.width = 'auto';
  309. dropper.style.height = '14px';
  310. dropperBtn.appendChild(dropper);
  311. div.appendChild(dropperBtn);
  312. mxEvent.addListener(clrInput, 'change', function()
  313. {
  314. picker.fromString(validateColorName(clrInput.value, true));
  315. });
  316. }
  317. mxEvent.addListener(input, 'change', function()
  318. {
  319. var value = input.value;
  320. picker.fromString(validateColorName(value, true));
  321. input.value = validateColorName(value,
  322. false, defaultColorLabel);
  323. selectInput();
  324. });
  325. input.style.width = w + 'px';
  326. mxUtils.br(div);
  327. // Adds recent colors
  328. createRecentColorTable();
  329. // Adds presets
  330. var table = addPresets(this.presetColors);
  331. table.style.marginBottom = '8px';
  332. table = addPresets(this.defaultColors);
  333. table.style.marginBottom = '16px';
  334. div.appendChild(center);
  335. var buttons = document.createElement('div');
  336. buttons.style.textAlign = 'right';
  337. buttons.style.whiteSpace = 'nowrap';
  338. var cancelBtn = mxUtils.button(mxResources.get('cancel'), function()
  339. {
  340. editorUi.hideDialog();
  341. if (cancelFn != null)
  342. {
  343. cancelFn();
  344. }
  345. });
  346. cancelBtn.className = 'geBtn';
  347. if (editorUi.editor.cancelFirst)
  348. {
  349. buttons.appendChild(cancelBtn);
  350. }
  351. var applyBtn = mxUtils.button(mxResources.get('apply'), doApply);
  352. applyBtn.className = 'geBtn gePrimaryBtn';
  353. buttons.appendChild(applyBtn);
  354. if (!editorUi.editor.cancelFirst)
  355. {
  356. buttons.appendChild(cancelBtn);
  357. }
  358. if (color != null)
  359. {
  360. if (color == 'default')
  361. {
  362. picker.fromString(defaultColorValue);
  363. input.value = defaultColorLabel;
  364. }
  365. else if (color == 'none')
  366. {
  367. picker.fromString('ffffff');
  368. input.value = 'none';
  369. }
  370. else
  371. {
  372. picker.fromString(color);
  373. }
  374. }
  375. div.appendChild(buttons);
  376. this.picker = picker;
  377. this.colorInput = input;
  378. mxEvent.addListener(input, 'keypress', function(e)
  379. {
  380. if (e.keyCode == 13)
  381. {
  382. doApply();
  383. }
  384. });
  385. // LATER: Only fires if input if focused, should always
  386. // fire if this dialog is showing.
  387. mxEvent.addListener(div, 'keydown', function(e)
  388. {
  389. if (e.keyCode == 27)
  390. {
  391. editorUi.hideDialog();
  392. if (cancelFn != null)
  393. {
  394. cancelFn();
  395. }
  396. mxEvent.consume(e);
  397. }
  398. });
  399. this.container = div;
  400. };
  401. /**
  402. * Creates function to apply value
  403. */
  404. ColorDialog.prototype.presetColors = ['E6D0DE', 'CDA2BE', 'B5739D', 'E1D5E7', 'C3ABD0', 'A680B8', 'D4E1F5', 'A9C4EB', '7EA6E0', 'D5E8D4', '9AC7BF', '67AB9F', 'D5E8D4', 'B9E0A5', '97D077', 'FFF2CC', 'FFE599', 'FFD966', 'FFF4C3', 'FFCE9F', 'FFB570', 'F8CECC', 'F19C99', 'EA6B66'];
  405. /**
  406. * Creates function to apply value
  407. */
  408. ColorDialog.prototype.colorNames = {};
  409. /**
  410. * Creates function to apply value
  411. */
  412. ColorDialog.prototype.defaultColors = ['none', 'FFFFFF', 'E6E6E6', 'CCCCCC', 'B3B3B3', '999999', '808080', '666666', '4D4D4D', '333333', '1A1A1A', '000000', 'FFCCCC', 'FFE6CC', 'FFFFCC', 'E6FFCC', 'CCFFCC', 'CCFFE6', 'CCFFFF', 'CCE5FF', 'CCCCFF', 'E5CCFF', 'FFCCFF', 'FFCCE6',
  413. 'FF9999', 'FFCC99', 'FFFF99', 'CCFF99', '99FF99', '99FFCC', '99FFFF', '99CCFF', '9999FF', 'CC99FF', 'FF99FF', 'FF99CC', 'FF6666', 'FFB366', 'FFFF66', 'B3FF66', '66FF66', '66FFB3', '66FFFF', '66B2FF', '6666FF', 'B266FF', 'FF66FF', 'FF66B3', 'FF3333', 'FF9933', 'FFFF33',
  414. '99FF33', '33FF33', '33FF99', '33FFFF', '3399FF', '3333FF', '9933FF', 'FF33FF', 'FF3399', 'FF0000', 'FF8000', 'FFFF00', '80FF00', '00FF00', '00FF80', '00FFFF', '007FFF', '0000FF', '7F00FF', 'FF00FF', 'FF0080', 'CC0000', 'CC6600', 'CCCC00', '66CC00', '00CC00', '00CC66',
  415. '00CCCC', '0066CC', '0000CC', '6600CC', 'CC00CC', 'CC0066', '990000', '994C00', '999900', '4D9900', '009900', '00994D', '009999', '004C99', '000099', '4C0099', '990099', '99004D', '660000', '663300', '666600', '336600', '006600', '006633', '006666', '003366', '000066',
  416. '330066', '660066', '660033', '330000', '331A00', '333300', '1A3300', '003300', '00331A', '003333', '001933', '000033', '190033', '330033', '33001A'];
  417. /**
  418. * Creates function to apply value
  419. */
  420. ColorDialog.prototype.createApplyFunction = function()
  421. {
  422. return ColorDialog.createApplyFunction(this.editorUi, this.currentColorKey);
  423. };
  424. /**
  425. * Creates function to apply value
  426. */
  427. ColorDialog.createApplyFunction = function(editorUi, colorKey)
  428. {
  429. return function(color)
  430. {
  431. var graph = editorUi.editor.graph;
  432. graph.getModel().beginUpdate();
  433. try
  434. {
  435. graph.setCellStyles(colorKey, color);
  436. editorUi.fireEvent(new mxEventObject('styleChanged', 'keys', [colorKey],
  437. 'values', [color], 'cells', graph.getSelectionCells()));
  438. }
  439. finally
  440. {
  441. graph.getModel().endUpdate();
  442. }
  443. };
  444. };
  445. /**
  446. *
  447. */
  448. ColorDialog.recentColors = [];
  449. /**
  450. * Adds recent color for later use.
  451. */
  452. ColorDialog.addRecentColor = function(color, max)
  453. {
  454. if (color != null)
  455. {
  456. mxUtils.remove(color, ColorDialog.recentColors);
  457. ColorDialog.recentColors.splice(0, 0, color);
  458. if (ColorDialog.recentColors.length >= max)
  459. {
  460. ColorDialog.recentColors.pop();
  461. }
  462. }
  463. };
  464. /**
  465. * Adds recent color for later use.
  466. */
  467. ColorDialog.resetRecentColors = function()
  468. {
  469. ColorDialog.recentColors = [];
  470. };
  471. /**
  472. * Constructs a new about dialog.
  473. */
  474. var AboutDialog = function(editorUi)
  475. {
  476. var div = document.createElement('div');
  477. div.setAttribute('align', 'center');
  478. var h3 = document.createElement('h3');
  479. mxUtils.write(h3, mxResources.get('about') + ' GraphEditor');
  480. div.appendChild(h3);
  481. var img = document.createElement('img');
  482. img.style.border = '0px';
  483. img.setAttribute('width', '176');
  484. img.setAttribute('width', '151');
  485. img.setAttribute('src', IMAGE_PATH + '/logo.png');
  486. div.appendChild(img);
  487. mxUtils.br(div);
  488. mxUtils.write(div, 'Powered by mxGraph ' + mxClient.VERSION);
  489. mxUtils.br(div);
  490. var link = document.createElement('a');
  491. link.setAttribute('href', 'http://www.jgraph.com/');
  492. link.setAttribute('target', '_blank');
  493. mxUtils.write(link, 'www.jgraph.com');
  494. div.appendChild(link);
  495. mxUtils.br(div);
  496. mxUtils.br(div);
  497. var closeBtn = mxUtils.button(mxResources.get('close'), function()
  498. {
  499. editorUi.hideDialog();
  500. });
  501. closeBtn.className = 'geBtn gePrimaryBtn';
  502. div.appendChild(closeBtn);
  503. this.container = div;
  504. };
  505. /**
  506. * Constructs a new textarea dialog.
  507. */
  508. var TextareaDialog = function(editorUi, title, url, fn, cancelFn, cancelTitle, w, h,
  509. addButtons, noHide, noWrap, applyTitle, helpLink, customButtons, header)
  510. {
  511. w = (w != null) ? w : 300;
  512. h = (h != null) ? h : 120;
  513. noHide = (noHide != null) ? noHide : false;
  514. var div = document.createElement('div');
  515. div.style.position = 'absolute';
  516. div.style.top = '20px';
  517. div.style.bottom = '20px';
  518. div.style.left = '20px';
  519. div.style.right = '20px';
  520. var top = document.createElement('div');
  521. top.style.position = 'absolute';
  522. top.style.left = '0px';
  523. top.style.right = '0px';
  524. var main = top.cloneNode(false);
  525. var buttons = top.cloneNode(false);
  526. top.style.top = '0px';
  527. top.style.height = '20px';
  528. main.style.top = '20px';
  529. main.style.bottom = '64px';
  530. buttons.style.bottom = '0px';
  531. buttons.style.height = '60px';
  532. buttons.style.textAlign = 'right';
  533. buttons.style.paddingTop = '14px';
  534. buttons.style.boxSizing = 'border-box';
  535. mxUtils.write(top, title);
  536. div.appendChild(top);
  537. div.appendChild(main);
  538. div.appendChild(buttons);
  539. if (header != null)
  540. {
  541. top.appendChild(header);
  542. }
  543. var nameInput = document.createElement('textarea');
  544. if (noWrap)
  545. {
  546. nameInput.setAttribute('wrap', 'off');
  547. }
  548. nameInput.setAttribute('spellcheck', 'false');
  549. nameInput.setAttribute('autocorrect', 'off');
  550. nameInput.setAttribute('autocomplete', 'off');
  551. nameInput.setAttribute('autocapitalize', 'off');
  552. mxUtils.write(nameInput, url || '');
  553. nameInput.style.resize = 'none';
  554. nameInput.style.outline = 'none';
  555. nameInput.style.position = 'absolute';
  556. nameInput.style.boxSizing = 'border-box';
  557. nameInput.style.top = '0px';
  558. nameInput.style.left = '0px';
  559. nameInput.style.height = '100%';
  560. nameInput.style.width = '100%';
  561. this.textarea = nameInput;
  562. this.init = function()
  563. {
  564. nameInput.focus();
  565. nameInput.scrollTop = 0;
  566. };
  567. main.appendChild(nameInput);
  568. if (helpLink != null && !editorUi.isOffline())
  569. {
  570. buttons.appendChild(editorUi.createHelpIcon(helpLink));
  571. }
  572. if (customButtons != null)
  573. {
  574. for (var i = 0; i < customButtons.length; i++)
  575. {
  576. (function(label, fn, title)
  577. {
  578. var customBtn = mxUtils.button(label, function(e)
  579. {
  580. fn(e, nameInput);
  581. });
  582. if (title != null)
  583. {
  584. customBtn.setAttribute('title', title);
  585. }
  586. customBtn.className = 'geBtn';
  587. buttons.appendChild(customBtn);
  588. })(customButtons[i][0], customButtons[i][1], customButtons[i][2]);
  589. }
  590. }
  591. var cancelBtn = mxUtils.button(cancelTitle || mxResources.get('cancel'), function()
  592. {
  593. editorUi.hideDialog();
  594. if (cancelFn != null)
  595. {
  596. cancelFn();
  597. }
  598. });
  599. cancelBtn.setAttribute('title', 'Escape');
  600. cancelBtn.className = 'geBtn';
  601. if (editorUi.editor.cancelFirst)
  602. {
  603. buttons.appendChild(cancelBtn);
  604. }
  605. if (addButtons != null)
  606. {
  607. addButtons(buttons, nameInput);
  608. }
  609. if (fn != null)
  610. {
  611. var genericBtn = mxUtils.button(applyTitle || mxResources.get('apply'), function()
  612. {
  613. if (!noHide)
  614. {
  615. editorUi.hideDialog();
  616. }
  617. fn(nameInput.value);
  618. });
  619. genericBtn.setAttribute('title', 'Ctrl+Enter');
  620. genericBtn.className = 'geBtn gePrimaryBtn';
  621. buttons.appendChild(genericBtn);
  622. mxEvent.addListener(nameInput, 'keypress', function(e)
  623. {
  624. if (e.keyCode == 13 && mxEvent.isControlDown(e))
  625. {
  626. genericBtn.click();
  627. }
  628. });
  629. }
  630. if (!editorUi.editor.cancelFirst)
  631. {
  632. buttons.appendChild(cancelBtn);
  633. }
  634. this.container = div;
  635. };
  636. /**
  637. * Constructs a new edit file dialog.
  638. */
  639. var EditDiagramDialog = function(editorUi)
  640. {
  641. var div = document.createElement('div');
  642. div.style.textAlign = 'right';
  643. var textarea = document.createElement('textarea');
  644. textarea.setAttribute('wrap', 'off');
  645. textarea.setAttribute('spellcheck', 'false');
  646. textarea.setAttribute('autocorrect', 'off');
  647. textarea.setAttribute('autocomplete', 'off');
  648. textarea.setAttribute('autocapitalize', 'off');
  649. textarea.style.overflow = 'auto';
  650. textarea.style.resize = 'none';
  651. textarea.style.width = '600px';
  652. textarea.style.height = '360px';
  653. textarea.style.marginBottom = '16px';
  654. var snapshot = editorUi.getDiagramSnapshot();
  655. textarea.value = mxUtils.getPrettyXml(snapshot.node);
  656. div.appendChild(textarea);
  657. this.init = function()
  658. {
  659. textarea.focus();
  660. };
  661. // Enables dropping files
  662. if (Graph.fileSupport)
  663. {
  664. function handleDrop(evt)
  665. {
  666. evt.stopPropagation();
  667. evt.preventDefault();
  668. if (evt.dataTransfer.files.length > 0)
  669. {
  670. var file = evt.dataTransfer.files[0];
  671. var reader = new FileReader();
  672. reader.onload = function(e)
  673. {
  674. textarea.value = e.target.result;
  675. };
  676. reader.readAsText(file);
  677. }
  678. else
  679. {
  680. textarea.value = editorUi.extractGraphModelFromEvent(evt);
  681. }
  682. };
  683. function handleDragOver(evt)
  684. {
  685. evt.stopPropagation();
  686. evt.preventDefault();
  687. };
  688. // Setup the dnd listeners.
  689. textarea.addEventListener('dragover', handleDragOver, false);
  690. textarea.addEventListener('drop', handleDrop, false);
  691. }
  692. var cancelBtn = mxUtils.button(mxResources.get('cancel'), function()
  693. {
  694. editorUi.hideDialog();
  695. });
  696. cancelBtn.className = 'geBtn';
  697. if (editorUi.editor.cancelFirst)
  698. {
  699. div.appendChild(cancelBtn);
  700. }
  701. var select = document.createElement('select');
  702. select.style.textOverflow = 'ellipsis';
  703. select.style.width = '196px';
  704. select.className = 'geBtn';
  705. if (editorUi.editor.graph.isEnabled())
  706. {
  707. var applyOption = document.createElement('option');
  708. applyOption.setAttribute('value', 'apply');
  709. mxUtils.write(applyOption, mxResources.get('apply',
  710. null, 'Update Existing Drawing'));
  711. select.appendChild(applyOption);
  712. }
  713. if (editorUi.editor.graph.isEnabled())
  714. {
  715. var insertOption = document.createElement('option');
  716. insertOption.setAttribute('value', 'insert');
  717. mxUtils.write(insertOption, mxResources.get('insert'));
  718. select.appendChild(insertOption);
  719. }
  720. var newOption = document.createElement('option');
  721. newOption.setAttribute('value', 'new');
  722. mxUtils.write(newOption, mxResources.get('openInNewWindow'));
  723. if (EditDiagramDialog.showNewWindowOption)
  724. {
  725. select.appendChild(newOption);
  726. }
  727. div.appendChild(select);
  728. var okBtn = mxUtils.button(mxResources.get('ok'), function()
  729. {
  730. // Removes all illegal control characters before parsing
  731. var data = Graph.zapGremlins(mxUtils.trim(textarea.value));
  732. var error = null;
  733. if (select.value == 'new')
  734. {
  735. editorUi.hideDialog();
  736. editorUi.editor.editAsNew(data);
  737. }
  738. else if (select.value == 'apply')
  739. {
  740. try
  741. {
  742. var node = mxUtils.parseXml(data).documentElement;
  743. editorUi.updateDiagramData(snapshot, node);
  744. editorUi.hideDialog();
  745. }
  746. catch (e)
  747. {
  748. error = e;
  749. }
  750. }
  751. else if (select.value == 'insert')
  752. {
  753. editorUi.editor.graph.model.beginUpdate();
  754. try
  755. {
  756. var doc = mxUtils.parseXml(data);
  757. var model = new mxGraphModel();
  758. var codec = new mxCodec(doc);
  759. codec.decode(doc.documentElement, model);
  760. var children = model.getChildren(model.getChildAt(model.getRoot(), 0));
  761. editorUi.editor.graph.setSelectionCells(editorUi.editor.graph.importCells(children));
  762. // LATER: Why is hideDialog between begin-/endUpdate faster?
  763. editorUi.hideDialog();
  764. }
  765. catch (e)
  766. {
  767. error = e;
  768. }
  769. finally
  770. {
  771. editorUi.editor.graph.model.endUpdate();
  772. }
  773. }
  774. if (error != null)
  775. {
  776. editorUi.handleError(error);
  777. }
  778. });
  779. okBtn.className = 'geBtn gePrimaryBtn';
  780. div.appendChild(okBtn);
  781. if (!editorUi.editor.cancelFirst)
  782. {
  783. div.appendChild(cancelBtn);
  784. }
  785. this.container = div;
  786. };
  787. /**
  788. *
  789. */
  790. EditDiagramDialog.showNewWindowOption = true;
  791. /**
  792. * Constructs a new export dialog.
  793. */
  794. var ExportDialog = function(editorUi)
  795. {
  796. var graph = editorUi.editor.graph;
  797. var bounds = graph.getGraphBounds();
  798. var scale = graph.view.scale;
  799. var width = Math.ceil(bounds.width / scale);
  800. var height = Math.ceil(bounds.height / scale);
  801. var row, td;
  802. var table = document.createElement('table');
  803. var tbody = document.createElement('tbody');
  804. table.setAttribute('cellpadding', (mxClient.IS_SF) ? '0' : '2');
  805. row = document.createElement('tr');
  806. td = document.createElement('td');
  807. td.style.fontSize = '10pt';
  808. td.style.width = '100px';
  809. mxUtils.write(td, mxResources.get('filename') + ':');
  810. row.appendChild(td);
  811. var nameInput = document.createElement('input');
  812. nameInput.setAttribute('value', editorUi.editor.getOrCreateFilename());
  813. nameInput.style.width = '180px';
  814. td = document.createElement('td');
  815. td.appendChild(nameInput);
  816. row.appendChild(td);
  817. tbody.appendChild(row);
  818. row = document.createElement('tr');
  819. td = document.createElement('td');
  820. td.style.fontSize = '10pt';
  821. mxUtils.write(td, mxResources.get('format') + ':');
  822. row.appendChild(td);
  823. var imageFormatSelect = document.createElement('select');
  824. imageFormatSelect.style.width = '180px';
  825. var pngOption = document.createElement('option');
  826. pngOption.setAttribute('value', 'png');
  827. mxUtils.write(pngOption, mxResources.get('formatPng'));
  828. imageFormatSelect.appendChild(pngOption);
  829. var gifOption = document.createElement('option');
  830. if (ExportDialog.showGifOption)
  831. {
  832. gifOption.setAttribute('value', 'gif');
  833. mxUtils.write(gifOption, mxResources.get('formatGif'));
  834. imageFormatSelect.appendChild(gifOption);
  835. }
  836. var jpgOption = document.createElement('option');
  837. jpgOption.setAttribute('value', 'jpg');
  838. mxUtils.write(jpgOption, mxResources.get('formatJpg'));
  839. imageFormatSelect.appendChild(jpgOption);
  840. var svgOption = document.createElement('option');
  841. svgOption.setAttribute('value', 'svg');
  842. mxUtils.write(svgOption, mxResources.get('formatSvg'));
  843. imageFormatSelect.appendChild(svgOption);
  844. if (ExportDialog.showXmlOption)
  845. {
  846. var xmlOption = document.createElement('option');
  847. xmlOption.setAttribute('value', 'xml');
  848. mxUtils.write(xmlOption, mxResources.get('formatXml'));
  849. imageFormatSelect.appendChild(xmlOption);
  850. }
  851. td = document.createElement('td');
  852. td.appendChild(imageFormatSelect);
  853. row.appendChild(td);
  854. tbody.appendChild(row);
  855. row = document.createElement('tr');
  856. td = document.createElement('td');
  857. td.style.fontSize = '10pt';
  858. mxUtils.write(td, mxResources.get('zoom') + ' (%):');
  859. row.appendChild(td);
  860. var zoomInput = document.createElement('input');
  861. zoomInput.setAttribute('type', 'number');
  862. zoomInput.setAttribute('value', '100');
  863. zoomInput.style.width = '180px';
  864. td = document.createElement('td');
  865. td.appendChild(zoomInput);
  866. row.appendChild(td);
  867. tbody.appendChild(row);
  868. row = document.createElement('tr');
  869. td = document.createElement('td');
  870. td.style.fontSize = '10pt';
  871. mxUtils.write(td, mxResources.get('width') + ':');
  872. row.appendChild(td);
  873. var widthInput = document.createElement('input');
  874. widthInput.setAttribute('value', width);
  875. widthInput.style.width = '180px';
  876. td = document.createElement('td');
  877. td.appendChild(widthInput);
  878. row.appendChild(td);
  879. tbody.appendChild(row);
  880. row = document.createElement('tr');
  881. td = document.createElement('td');
  882. td.style.fontSize = '10pt';
  883. mxUtils.write(td, mxResources.get('height') + ':');
  884. row.appendChild(td);
  885. var heightInput = document.createElement('input');
  886. heightInput.setAttribute('value', height);
  887. heightInput.style.width = '180px';
  888. td = document.createElement('td');
  889. td.appendChild(heightInput);
  890. row.appendChild(td);
  891. tbody.appendChild(row);
  892. row = document.createElement('tr');
  893. td = document.createElement('td');
  894. td.style.fontSize = '10pt';
  895. mxUtils.write(td, mxResources.get('dpi') + ':');
  896. row.appendChild(td);
  897. var dpiSelect = document.createElement('select');
  898. dpiSelect.style.width = '180px';
  899. var dpi100Option = document.createElement('option');
  900. dpi100Option.setAttribute('value', '100');
  901. mxUtils.write(dpi100Option, '100dpi');
  902. dpiSelect.appendChild(dpi100Option);
  903. var dpi200Option = document.createElement('option');
  904. dpi200Option.setAttribute('value', '200');
  905. mxUtils.write(dpi200Option, '200dpi');
  906. dpiSelect.appendChild(dpi200Option);
  907. var dpi300Option = document.createElement('option');
  908. dpi300Option.setAttribute('value', '300');
  909. mxUtils.write(dpi300Option, '300dpi');
  910. dpiSelect.appendChild(dpi300Option);
  911. var dpi400Option = document.createElement('option');
  912. dpi400Option.setAttribute('value', '400');
  913. mxUtils.write(dpi400Option, '400dpi');
  914. dpiSelect.appendChild(dpi400Option);
  915. var dpiCustOption = document.createElement('option');
  916. dpiCustOption.setAttribute('value', 'custom');
  917. mxUtils.write(dpiCustOption, mxResources.get('custom'));
  918. dpiSelect.appendChild(dpiCustOption);
  919. var customDpi = document.createElement('input');
  920. customDpi.style.width = '180px';
  921. customDpi.style.display = 'none';
  922. customDpi.setAttribute('value', '100');
  923. customDpi.setAttribute('type', 'number');
  924. customDpi.setAttribute('min', '50');
  925. customDpi.setAttribute('step', '50');
  926. var zoomUserChanged = false;
  927. mxEvent.addListener(dpiSelect, 'change', function()
  928. {
  929. if (this.value == 'custom')
  930. {
  931. this.style.display = 'none';
  932. customDpi.style.display = '';
  933. customDpi.focus();
  934. }
  935. else
  936. {
  937. customDpi.value = this.value;
  938. if (!zoomUserChanged)
  939. {
  940. zoomInput.value = this.value;
  941. }
  942. }
  943. });
  944. mxEvent.addListener(customDpi, 'change', function()
  945. {
  946. var dpi = parseInt(customDpi.value);
  947. if (isNaN(dpi) || dpi <= 0)
  948. {
  949. customDpi.style.backgroundColor = 'red';
  950. }
  951. else
  952. {
  953. customDpi.style.backgroundColor = '';
  954. if (!zoomUserChanged)
  955. {
  956. zoomInput.value = dpi;
  957. }
  958. }
  959. });
  960. td = document.createElement('td');
  961. td.appendChild(dpiSelect);
  962. td.appendChild(customDpi);
  963. row.appendChild(td);
  964. tbody.appendChild(row);
  965. row = document.createElement('tr');
  966. td = document.createElement('td');
  967. td.style.fontSize = '10pt';
  968. mxUtils.write(td, mxResources.get('background') + ':');
  969. row.appendChild(td);
  970. var transparentCheckbox = document.createElement('input');
  971. transparentCheckbox.setAttribute('type', 'checkbox');
  972. transparentCheckbox.checked = graph.background == null || graph.background == mxConstants.NONE;
  973. td = document.createElement('td');
  974. td.appendChild(transparentCheckbox);
  975. mxUtils.write(td, mxResources.get('transparent'));
  976. row.appendChild(td);
  977. tbody.appendChild(row);
  978. row = document.createElement('tr');
  979. td = document.createElement('td');
  980. td.style.fontSize = '10pt';
  981. mxUtils.write(td, mxResources.get('grid') + ':');
  982. row.appendChild(td);
  983. var gridCheckbox = document.createElement('input');
  984. gridCheckbox.setAttribute('type', 'checkbox');
  985. gridCheckbox.checked = false;
  986. td = document.createElement('td');
  987. td.appendChild(gridCheckbox);
  988. row.appendChild(td);
  989. tbody.appendChild(row);
  990. row = document.createElement('tr');
  991. td = document.createElement('td');
  992. td.style.fontSize = '10pt';
  993. mxUtils.write(td, mxResources.get('borderWidth') + ':');
  994. row.appendChild(td);
  995. var borderInput = document.createElement('input');
  996. borderInput.setAttribute('type', 'number');
  997. borderInput.setAttribute('value', ExportDialog.lastBorderValue);
  998. borderInput.style.width = '180px';
  999. td = document.createElement('td');
  1000. td.appendChild(borderInput);
  1001. row.appendChild(td);
  1002. tbody.appendChild(row);
  1003. table.appendChild(tbody);
  1004. // Handles changes in the export format
  1005. function formatChanged()
  1006. {
  1007. var name = nameInput.value;
  1008. var dot = name.lastIndexOf('.');
  1009. if (dot > 0)
  1010. {
  1011. nameInput.value = name.substring(0, dot + 1) + imageFormatSelect.value;
  1012. }
  1013. else
  1014. {
  1015. nameInput.value = name + '.' + imageFormatSelect.value;
  1016. }
  1017. if (imageFormatSelect.value === 'xml')
  1018. {
  1019. zoomInput.setAttribute('disabled', 'true');
  1020. widthInput.setAttribute('disabled', 'true');
  1021. heightInput.setAttribute('disabled', 'true');
  1022. borderInput.setAttribute('disabled', 'true');
  1023. }
  1024. else
  1025. {
  1026. zoomInput.removeAttribute('disabled');
  1027. widthInput.removeAttribute('disabled');
  1028. heightInput.removeAttribute('disabled');
  1029. borderInput.removeAttribute('disabled');
  1030. }
  1031. if (imageFormatSelect.value === 'png' || imageFormatSelect.value === 'svg' || imageFormatSelect.value === 'pdf')
  1032. {
  1033. transparentCheckbox.removeAttribute('disabled');
  1034. }
  1035. else
  1036. {
  1037. transparentCheckbox.setAttribute('disabled', 'disabled');
  1038. }
  1039. if (imageFormatSelect.value === 'png' || imageFormatSelect.value === 'jpg' || imageFormatSelect.value === 'pdf')
  1040. {
  1041. gridCheckbox.removeAttribute('disabled');
  1042. }
  1043. else
  1044. {
  1045. gridCheckbox.setAttribute('disabled', 'disabled');
  1046. }
  1047. if (imageFormatSelect.value === 'png')
  1048. {
  1049. dpiSelect.removeAttribute('disabled');
  1050. customDpi.removeAttribute('disabled');
  1051. }
  1052. else
  1053. {
  1054. dpiSelect.setAttribute('disabled', 'disabled');
  1055. customDpi.setAttribute('disabled', 'disabled');
  1056. }
  1057. };
  1058. mxEvent.addListener(imageFormatSelect, 'change', formatChanged);
  1059. formatChanged();
  1060. function checkValues()
  1061. {
  1062. if (widthInput.value * heightInput.value > MAX_AREA || widthInput.value <= 0)
  1063. {
  1064. widthInput.style.backgroundColor = 'red';
  1065. }
  1066. else
  1067. {
  1068. widthInput.style.backgroundColor = '';
  1069. }
  1070. if (widthInput.value * heightInput.value > MAX_AREA || heightInput.value <= 0)
  1071. {
  1072. heightInput.style.backgroundColor = 'red';
  1073. }
  1074. else
  1075. {
  1076. heightInput.style.backgroundColor = '';
  1077. }
  1078. };
  1079. mxEvent.addListener(zoomInput, 'change', function()
  1080. {
  1081. zoomUserChanged = true;
  1082. var s = Math.max(0, parseFloat(zoomInput.value) || 100) / 100;
  1083. zoomInput.value = parseFloat((s * 100).toFixed(2));
  1084. if (width > 0)
  1085. {
  1086. widthInput.value = Math.floor(width * s);
  1087. heightInput.value = Math.floor(height * s);
  1088. }
  1089. else
  1090. {
  1091. zoomInput.value = '100';
  1092. widthInput.value = width;
  1093. heightInput.value = height;
  1094. }
  1095. checkValues();
  1096. });
  1097. mxEvent.addListener(widthInput, 'change', function()
  1098. {
  1099. var s = parseInt(widthInput.value) / width;
  1100. if (s > 0)
  1101. {
  1102. zoomInput.value = parseFloat((s * 100).toFixed(2));
  1103. heightInput.value = Math.floor(height * s);
  1104. }
  1105. else
  1106. {
  1107. zoomInput.value = '100';
  1108. widthInput.value = width;
  1109. heightInput.value = height;
  1110. }
  1111. checkValues();
  1112. });
  1113. mxEvent.addListener(heightInput, 'change', function()
  1114. {
  1115. var s = parseInt(heightInput.value) / height;
  1116. if (s > 0)
  1117. {
  1118. zoomInput.value = parseFloat((s * 100).toFixed(2));
  1119. widthInput.value = Math.floor(width * s);
  1120. }
  1121. else
  1122. {
  1123. zoomInput.value = '100';
  1124. widthInput.value = width;
  1125. heightInput.value = height;
  1126. }
  1127. checkValues();
  1128. });
  1129. row = document.createElement('tr');
  1130. td = document.createElement('td');
  1131. td.setAttribute('align', 'right');
  1132. td.style.paddingTop = '22px';
  1133. td.colSpan = 2;
  1134. var saveBtn = mxUtils.button(mxResources.get('export'), mxUtils.bind(this, function()
  1135. {
  1136. if (parseInt(zoomInput.value) <= 0)
  1137. {
  1138. mxUtils.alert(mxResources.get('drawingEmpty'));
  1139. }
  1140. else
  1141. {
  1142. var name = nameInput.value;
  1143. var format = imageFormatSelect.value;
  1144. var s = Math.max(0, parseFloat(zoomInput.value) || 100) / 100;
  1145. var b = Math.max(0, parseInt(borderInput.value));
  1146. var bg = graph.background;
  1147. var dpi = Math.max(1, parseInt(customDpi.value));
  1148. if ((format == 'svg' || format == 'png' || format == 'pdf') && transparentCheckbox.checked)
  1149. {
  1150. bg = null;
  1151. }
  1152. else if (bg == null || bg == mxConstants.NONE)
  1153. {
  1154. bg = '#ffffff';
  1155. }
  1156. ExportDialog.lastBorderValue = b;
  1157. ExportDialog.exportFile(editorUi, name, format, bg, s, b, dpi, gridCheckbox.checked);
  1158. }
  1159. }));
  1160. saveBtn.className = 'geBtn gePrimaryBtn';
  1161. var cancelBtn = mxUtils.button(mxResources.get('cancel'), function()
  1162. {
  1163. editorUi.hideDialog();
  1164. });
  1165. cancelBtn.className = 'geBtn';
  1166. if (editorUi.editor.cancelFirst)
  1167. {
  1168. td.appendChild(cancelBtn);
  1169. td.appendChild(saveBtn);
  1170. }
  1171. else
  1172. {
  1173. td.appendChild(saveBtn);
  1174. td.appendChild(cancelBtn);
  1175. }
  1176. row.appendChild(td);
  1177. tbody.appendChild(row);
  1178. table.appendChild(tbody);
  1179. this.container = table;
  1180. };
  1181. /**
  1182. * Remembers last value for border.
  1183. */
  1184. ExportDialog.lastBorderValue = 0;
  1185. /**
  1186. * Global switches for the export dialog.
  1187. */
  1188. ExportDialog.showGifOption = true;
  1189. /**
  1190. * Global switches for the export dialog.
  1191. */
  1192. ExportDialog.showXmlOption = true;
  1193. /**
  1194. * Hook for getting the export format. Returns null for the default
  1195. * intermediate XML export format or a function that returns the
  1196. * parameter and value to be used in the request in the form
  1197. * key=value, where value should be URL encoded.
  1198. */
  1199. ExportDialog.exportFile = function(editorUi, name, format, bg, s, b, dpi, grid)
  1200. {
  1201. var graph = editorUi.editor.graph;
  1202. if (format == 'xml')
  1203. {
  1204. ExportDialog.saveLocalFile(editorUi, mxUtils.getXml(editorUi.editor.getGraphXml()), name, format);
  1205. }
  1206. else if (format == 'svg')
  1207. {
  1208. ExportDialog.saveLocalFile(editorUi, mxUtils.getXml(graph.getSvg(bg, s, b)), name, format);
  1209. }
  1210. else
  1211. {
  1212. var bounds = graph.getGraphBounds();
  1213. // New image export
  1214. var xmlDoc = mxUtils.createXmlDocument();
  1215. var root = xmlDoc.createElement('output');
  1216. xmlDoc.appendChild(root);
  1217. // Renders graph. Offset will be multiplied with state's scale when painting state.
  1218. var xmlCanvas = new mxXmlCanvas2D(root);
  1219. xmlCanvas.translate(Math.floor((b / s - bounds.x) / graph.view.scale),
  1220. Math.floor((b / s - bounds.y) / graph.view.scale));
  1221. xmlCanvas.scale(s / graph.view.scale);
  1222. var imgExport = new mxImageExport()
  1223. imgExport.drawState(graph.getView().getState(graph.model.root), xmlCanvas);
  1224. // Puts request data together
  1225. var param = 'xml=' + encodeURIComponent(mxUtils.getXml(root));
  1226. var w = Math.ceil(bounds.width * s / graph.view.scale + 2 * b);
  1227. var h = Math.ceil(bounds.height * s / graph.view.scale + 2 * b);
  1228. // Requests image if request is valid
  1229. if (param.length <= MAX_REQUEST_SIZE && w * h < MAX_AREA)
  1230. {
  1231. editorUi.hideDialog();
  1232. var req = new mxXmlRequest(EXPORT_URL, 'format=' + format +
  1233. '&filename=' + encodeURIComponent(name) +
  1234. '&bg=' + ((bg != null) ? bg : 'none') +
  1235. '&w=' + w + '&h=' + h + '&' + param +
  1236. '&dpi=' + dpi);
  1237. req.simulate(document, '_blank');
  1238. }
  1239. else
  1240. {
  1241. mxUtils.alert(mxResources.get('drawingTooLarge'));
  1242. }
  1243. }
  1244. };
  1245. /**
  1246. * Hook for getting the export format. Returns null for the default
  1247. * intermediate XML export format or a function that returns the
  1248. * parameter and value to be used in the request in the form
  1249. * key=value, where value should be URL encoded.
  1250. */
  1251. ExportDialog.saveLocalFile = function(editorUi, data, filename, format)
  1252. {
  1253. if (data.length < MAX_REQUEST_SIZE)
  1254. {
  1255. editorUi.hideDialog();
  1256. var req = new mxXmlRequest(SAVE_URL, 'xml=' + encodeURIComponent(data) + '&filename=' +
  1257. encodeURIComponent(filename) + '&format=' + format);
  1258. req.simulate(document, '_blank');
  1259. }
  1260. else
  1261. {
  1262. mxUtils.alert(mxResources.get('drawingTooLarge'));
  1263. mxUtils.popup(xml);
  1264. }
  1265. };
  1266. /**
  1267. * Constructs a new metadata dialog.
  1268. */
  1269. var EditDataDialog = function(ui, cell)
  1270. {
  1271. var div = document.createElement('div');
  1272. var graph = ui.editor.graph;
  1273. var value = graph.getModel().getValue(cell);
  1274. // Converts the value to an XML node
  1275. if (!mxUtils.isNode(value))
  1276. {
  1277. var doc = mxUtils.createXmlDocument();
  1278. var obj = doc.createElement('object');
  1279. obj.setAttribute('label', value || '');
  1280. value = obj;
  1281. }
  1282. var meta = {};
  1283. try
  1284. {
  1285. var temp = mxUtils.getValue(ui.editor.graph.getCurrentCellStyle(cell), 'metaData', null);
  1286. if (temp != null)
  1287. {
  1288. meta = JSON.parse(temp);
  1289. }
  1290. }
  1291. catch (e)
  1292. {
  1293. // ignore
  1294. }
  1295. // Creates the dialog contents
  1296. var form = new mxForm('properties');
  1297. form.table.style.width = '100%';
  1298. var attrs = value.attributes;
  1299. var names = [];
  1300. var texts = [];
  1301. var count = 0;
  1302. var id = (EditDataDialog.getDisplayIdForCell != null) ?
  1303. EditDataDialog.getDisplayIdForCell(ui, cell) : null;
  1304. var addRemoveButton = function(text, name)
  1305. {
  1306. var wrapper = document.createElement('div');
  1307. wrapper.style.position = 'relative';
  1308. wrapper.style.paddingRight = '20px';
  1309. wrapper.style.boxSizing = 'border-box';
  1310. wrapper.style.width = '100%';
  1311. var removeAttr = document.createElement('a');
  1312. var img = mxUtils.createImage(Dialog.prototype.closeImage);
  1313. img.style.height = '9px';
  1314. img.style.fontSize = '9px';
  1315. img.style.marginBottom = (mxClient.IS_IE11) ? '-1px' : '5px';
  1316. removeAttr.className = 'geButton';
  1317. removeAttr.setAttribute('title', mxResources.get('delete'));
  1318. removeAttr.style.position = 'absolute';
  1319. removeAttr.style.top = '4px';
  1320. removeAttr.style.right = '0px';
  1321. removeAttr.style.margin = '0px';
  1322. removeAttr.style.width = '9px';
  1323. removeAttr.style.height = '9px';
  1324. removeAttr.style.cursor = 'pointer';
  1325. removeAttr.appendChild(img);
  1326. var removeAttrFn = (function(name)
  1327. {
  1328. return function()
  1329. {
  1330. var count = 0;
  1331. for (var j = 0; j < names.length; j++)
  1332. {
  1333. if (names[j] == name)
  1334. {
  1335. texts[j] = null;
  1336. form.table.deleteRow(count + ((id != null) ? 1 : 0));
  1337. break;
  1338. }
  1339. if (texts[j] != null)
  1340. {
  1341. count++;
  1342. }
  1343. }
  1344. };
  1345. })(name);
  1346. mxEvent.addListener(removeAttr, 'click', removeAttrFn);
  1347. var parent = text.parentNode;
  1348. wrapper.appendChild(text);
  1349. wrapper.appendChild(removeAttr);
  1350. parent.appendChild(wrapper);
  1351. };
  1352. var addTextArea = function(index, name, value)
  1353. {
  1354. names[index] = name;
  1355. texts[index] = form.addTextarea(names[count] + ':', value, 2);
  1356. texts[index].style.width = '100%';
  1357. if (value.indexOf('\n') > 0)
  1358. {
  1359. texts[index].setAttribute('rows', '2');
  1360. }
  1361. addRemoveButton(texts[index], name);
  1362. if (meta[name] != null && meta[name].editable == false)
  1363. {
  1364. texts[index].setAttribute('disabled', 'disabled');
  1365. }
  1366. };
  1367. var temp = [];
  1368. var isLayer = graph.getModel().getParent(cell) == graph.getModel().getRoot();
  1369. var style = graph.getCellStyle(cell);
  1370. for (var i = 0; i < attrs.length; i++)
  1371. {
  1372. if ((attrs[i].nodeName != 'label' || style['metaEdit'] == '1' ||
  1373. Graph.translateDiagram || isLayer) &&
  1374. attrs[i].nodeName != 'placeholders')
  1375. {
  1376. temp.push({name: attrs[i].nodeName, value: attrs[i].nodeValue});
  1377. }
  1378. }
  1379. // Sorts by name
  1380. temp.sort(function(a, b)
  1381. {
  1382. if (a.name == 'label')
  1383. {
  1384. return 1;
  1385. }
  1386. else if (b.name == 'label')
  1387. {
  1388. return -1;
  1389. }
  1390. else if (a.name < b.name)
  1391. {
  1392. return -1;
  1393. }
  1394. else if (a.name > b.name)
  1395. {
  1396. return 1;
  1397. }
  1398. else
  1399. {
  1400. return 0;
  1401. }
  1402. });
  1403. if (id != null)
  1404. {
  1405. var text = document.createElement('div');
  1406. text.style.width = '100%';
  1407. text.style.fontSize = '11px';
  1408. text.style.textAlign = 'center';
  1409. mxUtils.write(text, id);
  1410. var idInput = form.addField(mxResources.get('id') + ':', text);
  1411. mxEvent.addListener(text, 'dblclick', function(evt)
  1412. {
  1413. var dlg = new FilenameDialog(ui, id, mxResources.get('apply'),
  1414. mxUtils.bind(this, function(value)
  1415. {
  1416. if (value != null && value.length > 0 && value != id)
  1417. {
  1418. if (graph.model.isRoot(cell))
  1419. {
  1420. var page = ui.getPageById(id);
  1421. if (page != null)
  1422. {
  1423. if (ui.getPageById(value) == null)
  1424. {
  1425. var index = ui.getPageIndex(page);
  1426. if (index >= 0)
  1427. {
  1428. ui.removePage(page);
  1429. page.node.setAttribute('id', value);
  1430. id = value;
  1431. idInput.innerHTML = mxUtils.htmlEntities(value);
  1432. ui.insertPage(page, index);
  1433. }
  1434. }
  1435. else
  1436. {
  1437. ui.handleError({message: mxResources.get('alreadyExst',
  1438. [mxResources.get('page')])});
  1439. }
  1440. }
  1441. }
  1442. else
  1443. {
  1444. if (graph.getModel().getCell(value) == null)
  1445. {
  1446. graph.getModel().cellRemoved(cell);
  1447. cell.setId(value);
  1448. id = value;
  1449. idInput.innerHTML = mxUtils.htmlEntities(value);
  1450. graph.getModel().cellAdded(cell);
  1451. }
  1452. else
  1453. {
  1454. ui.handleError({message: mxResources.get('alreadyExst', [value])});
  1455. }
  1456. }
  1457. }
  1458. }), mxResources.get('id'));
  1459. ui.showDialog(dlg.container, 300, 80, true, true);
  1460. dlg.init();
  1461. });
  1462. }
  1463. for (var i = 0; i < temp.length; i++)
  1464. {
  1465. addTextArea(count, temp[i].name, temp[i].value);
  1466. count++;
  1467. }
  1468. var top = document.createElement('div');
  1469. top.style.position = 'absolute';
  1470. top.style.top = '30px';
  1471. top.style.left = '30px';
  1472. top.style.right = '30px';
  1473. top.style.bottom = '80px';
  1474. top.style.overflowY = 'auto';
  1475. top.appendChild(form.table);
  1476. var newProp = document.createElement('div');
  1477. newProp.style.display = 'flex';
  1478. newProp.style.alignItems = 'center';
  1479. newProp.style.boxSizing = 'border-box';
  1480. newProp.style.paddingRight = '160px';
  1481. newProp.style.whiteSpace = 'nowrap';
  1482. newProp.style.marginTop = '6px';
  1483. newProp.style.width = '100%';
  1484. var nameInput = document.createElement('input');
  1485. nameInput.setAttribute('placeholder', mxResources.get('enterPropertyName'));
  1486. nameInput.setAttribute('type', 'text');
  1487. nameInput.setAttribute('size', (mxClient.IS_IE || mxClient.IS_IE11) ? '36' : '40');
  1488. nameInput.style.boxSizing = 'border-box';
  1489. nameInput.style.borderWidth = '1px';
  1490. nameInput.style.borderStyle = 'solid';
  1491. nameInput.style.marginLeft = '2px';
  1492. nameInput.style.padding = '4px';
  1493. nameInput.style.width = '100%';
  1494. newProp.appendChild(nameInput);
  1495. top.appendChild(newProp);
  1496. div.appendChild(top);
  1497. var addBtn = mxUtils.button(mxResources.get('addProperty'), function()
  1498. {
  1499. var name = nameInput.value;
  1500. // Avoid ':' in attribute names which seems to be valid in Chrome
  1501. if (name.length > 0 && name != 'label' && name != 'id' &&
  1502. name != 'placeholders' && name.indexOf(':') < 0)
  1503. {
  1504. try
  1505. {
  1506. var idx = mxUtils.indexOf(names, name);
  1507. if (idx >= 0 && texts[idx] != null)
  1508. {
  1509. texts[idx].focus();
  1510. }
  1511. else
  1512. {
  1513. // Checks if the name is valid
  1514. var clone = value.cloneNode(false);
  1515. clone.setAttribute(name, '');
  1516. if (idx >= 0)
  1517. {
  1518. names.splice(idx, 1);
  1519. texts.splice(idx, 1);
  1520. }
  1521. names.push(name);
  1522. var text = form.addTextarea(name + ':', '', 2);
  1523. text.style.width = '100%';
  1524. texts.push(text);
  1525. addRemoveButton(text, name);
  1526. text.focus();
  1527. }
  1528. addBtn.setAttribute('disabled', 'disabled');
  1529. nameInput.value = '';
  1530. }
  1531. catch (e)
  1532. {
  1533. mxUtils.alert(e);
  1534. }
  1535. }
  1536. else
  1537. {
  1538. mxUtils.alert(mxResources.get('invalidName'));
  1539. }
  1540. });
  1541. mxEvent.addListener(nameInput, 'keypress', function(e)
  1542. {
  1543. if (e.keyCode == 13 )
  1544. {
  1545. addBtn.click();
  1546. }
  1547. });
  1548. this.init = function()
  1549. {
  1550. if (texts.length > 0)
  1551. {
  1552. texts[0].focus();
  1553. }
  1554. else
  1555. {
  1556. nameInput.focus();
  1557. }
  1558. };
  1559. addBtn.setAttribute('title', mxResources.get('addProperty'));
  1560. addBtn.setAttribute('disabled', 'disabled');
  1561. addBtn.style.textOverflow = 'ellipsis';
  1562. addBtn.style.position = 'absolute';
  1563. addBtn.style.overflow = 'hidden';
  1564. addBtn.style.width = '144px';
  1565. addBtn.style.right = '0px';
  1566. addBtn.className = 'geBtn';
  1567. newProp.appendChild(addBtn);
  1568. var cancelBtn = mxUtils.button(mxResources.get('cancel'), function()
  1569. {
  1570. ui.hideDialog.apply(ui, arguments);
  1571. });
  1572. cancelBtn.setAttribute('title', 'Escape');
  1573. cancelBtn.className = 'geBtn';
  1574. var exportBtn = mxUtils.button(mxResources.get('export'), mxUtils.bind(this, function(evt)
  1575. {
  1576. var result = graph.getDataForCells([cell], true);
  1577. var dlg = new EmbedDialog(ui, JSON.stringify(result, null, 2), null, null, function()
  1578. {
  1579. console.log(result);
  1580. ui.alert('Written to Console (Dev Tools)');
  1581. }, mxResources.get('export'), null, 'Console', 'data.json');
  1582. ui.showDialog(dlg.container, 450, 240, true, true);
  1583. dlg.init();
  1584. }));
  1585. exportBtn.setAttribute('title', mxResources.get('export'));
  1586. exportBtn.className = 'geBtn';
  1587. var applyBtn = mxUtils.button(mxResources.get('apply'), function()
  1588. {
  1589. try
  1590. {
  1591. ui.hideDialog.apply(ui, arguments);
  1592. // Clones and updates the value
  1593. value = value.cloneNode(true);
  1594. var removeLabel = false;
  1595. for (var i = 0; i < names.length; i++)
  1596. {
  1597. if (texts[i] == null)
  1598. {
  1599. value.removeAttribute(names[i]);
  1600. }
  1601. else
  1602. {
  1603. value.setAttribute(names[i], texts[i].value);
  1604. removeLabel = removeLabel || (names[i] == 'placeholder' &&
  1605. value.getAttribute('placeholders') == '1');
  1606. }
  1607. }
  1608. // Removes label if placeholder is assigned
  1609. if (removeLabel)
  1610. {
  1611. value.removeAttribute('label');
  1612. }
  1613. // Updates the value of the cell (undoable)
  1614. graph.getModel().setValue(cell, value);
  1615. }
  1616. catch (e)
  1617. {
  1618. mxUtils.alert(e);
  1619. }
  1620. });
  1621. applyBtn.setAttribute('title', 'Ctrl+Enter');
  1622. applyBtn.className = 'geBtn gePrimaryBtn';
  1623. mxEvent.addListener(div, 'keypress', function(e)
  1624. {
  1625. if (e.keyCode == 13 && mxEvent.isControlDown(e))
  1626. {
  1627. applyBtn.click();
  1628. }
  1629. });
  1630. function updateAddBtn()
  1631. {
  1632. if (nameInput.value.length > 0)
  1633. {
  1634. addBtn.removeAttribute('disabled');
  1635. }
  1636. else
  1637. {
  1638. addBtn.setAttribute('disabled', 'disabled');
  1639. }
  1640. };
  1641. mxEvent.addListener(nameInput, 'keyup', updateAddBtn);
  1642. // Catches all changes that don't fire a keyup (such as paste via mouse)
  1643. mxEvent.addListener(nameInput, 'change', updateAddBtn);
  1644. var buttons = document.createElement('div');
  1645. buttons.style.cssText = 'position:absolute;left:30px;right:30px;text-align:right;bottom:30px;height:40px;'
  1646. if (ui.editor.graph.getModel().isVertex(cell) || ui.editor.graph.getModel().isEdge(cell))
  1647. {
  1648. var replace = document.createElement('span');
  1649. replace.style.marginRight = '10px';
  1650. var input = document.createElement('input');
  1651. input.setAttribute('type', 'checkbox');
  1652. input.style.marginRight = '6px';
  1653. if (value.getAttribute('placeholders') == '1')
  1654. {
  1655. input.setAttribute('checked', 'checked');
  1656. input.defaultChecked = true;
  1657. }
  1658. mxEvent.addListener(input, 'click', function()
  1659. {
  1660. if (value.getAttribute('placeholders') == '1')
  1661. {
  1662. value.removeAttribute('placeholders');
  1663. }
  1664. else
  1665. {
  1666. value.setAttribute('placeholders', '1');
  1667. }
  1668. });
  1669. replace.appendChild(input);
  1670. mxUtils.write(replace, mxResources.get('placeholders'));
  1671. if (EditDataDialog.placeholderHelpLink != null)
  1672. {
  1673. replace.appendChild(ui.createHelpIcon(
  1674. EditDataDialog.placeholderHelpLink));
  1675. }
  1676. buttons.appendChild(replace);
  1677. }
  1678. if (ui.editor.cancelFirst)
  1679. {
  1680. buttons.appendChild(cancelBtn);
  1681. }
  1682. buttons.appendChild(exportBtn);
  1683. buttons.appendChild(applyBtn);
  1684. if (!ui.editor.cancelFirst)
  1685. {
  1686. buttons.appendChild(cancelBtn);
  1687. }
  1688. div.appendChild(buttons);
  1689. this.container = div;
  1690. };
  1691. /**
  1692. * Optional help link.
  1693. */
  1694. EditDataDialog.getDisplayIdForCell = function(ui, cell)
  1695. {
  1696. var id = null;
  1697. if (ui.editor.graph.getModel().getParent(cell) != null)
  1698. {
  1699. id = cell.getId();
  1700. }
  1701. return id;
  1702. };
  1703. /**
  1704. * Optional help link.
  1705. */
  1706. EditDataDialog.placeholderHelpLink = null;
  1707. /**
  1708. * Constructs a new link dialog.
  1709. */
  1710. var LinkDialog = function(editorUi, initialValue, btnLabel, fn)
  1711. {
  1712. var div = document.createElement('div');
  1713. mxUtils.write(div, mxResources.get('editLink') + ':');
  1714. var inner = document.createElement('div');
  1715. inner.className = 'geTitle';
  1716. inner.style.backgroundColor = 'transparent';
  1717. inner.style.borderColor = 'transparent';
  1718. inner.style.whiteSpace = 'nowrap';
  1719. inner.style.textOverflow = 'clip';
  1720. inner.style.cursor = 'default';
  1721. inner.style.paddingRight = '20px';
  1722. var linkInput = document.createElement('input');
  1723. linkInput.setAttribute('value', initialValue);
  1724. linkInput.setAttribute('placeholder', 'http://www.example.com/');
  1725. linkInput.setAttribute('type', 'text');
  1726. linkInput.style.marginTop = '6px';
  1727. linkInput.style.width = '400px';
  1728. linkInput.style.backgroundImage = 'url(\'' + Dialog.prototype.clearImage + '\')';
  1729. linkInput.style.backgroundRepeat = 'no-repeat';
  1730. linkInput.style.backgroundPosition = '100% 50%';
  1731. linkInput.style.paddingRight = '14px';
  1732. var cross = document.createElement('div');
  1733. cross.setAttribute('title', mxResources.get('reset'));
  1734. cross.style.position = 'relative';
  1735. cross.style.left = '-16px';
  1736. cross.style.width = '12px';
  1737. cross.style.height = '14px';
  1738. cross.style.cursor = 'pointer';
  1739. // Workaround for inline-block not supported in IE
  1740. cross.style.display = 'inline-block';
  1741. cross.style.top = '3px';
  1742. // Needed to block event transparency in IE
  1743. cross.style.background = 'url(' + IMAGE_PATH + '/transparent.gif)';
  1744. mxEvent.addListener(cross, 'click', function()
  1745. {
  1746. linkInput.value = '';
  1747. linkInput.focus();
  1748. });
  1749. inner.appendChild(linkInput);
  1750. inner.appendChild(cross);
  1751. div.appendChild(inner);
  1752. this.init = function()
  1753. {
  1754. linkInput.focus();
  1755. if (mxClient.IS_GC || mxClient.IS_FF || document.documentMode >= 5)
  1756. {
  1757. linkInput.select();
  1758. }
  1759. else
  1760. {
  1761. document.execCommand('selectAll', false, null);
  1762. }
  1763. };
  1764. var btns = document.createElement('div');
  1765. btns.style.marginTop = '18px';
  1766. btns.style.textAlign = 'right';
  1767. mxEvent.addListener(linkInput, 'keypress', function(e)
  1768. {
  1769. if (e.keyCode == 13)
  1770. {
  1771. editorUi.hideDialog();
  1772. fn(linkInput.value);
  1773. }
  1774. });
  1775. var cancelBtn = mxUtils.button(mxResources.get('cancel'), function()
  1776. {
  1777. editorUi.hideDialog();
  1778. });
  1779. cancelBtn.className = 'geBtn';
  1780. if (editorUi.editor.cancelFirst)
  1781. {
  1782. btns.appendChild(cancelBtn);
  1783. }
  1784. var mainBtn = mxUtils.button(btnLabel, function()
  1785. {
  1786. editorUi.hideDialog();
  1787. fn(linkInput.value);
  1788. });
  1789. mainBtn.className = 'geBtn gePrimaryBtn';
  1790. btns.appendChild(mainBtn);
  1791. if (!editorUi.editor.cancelFirst)
  1792. {
  1793. btns.appendChild(cancelBtn);
  1794. }
  1795. div.appendChild(btns);
  1796. this.container = div;
  1797. };
  1798. /**
  1799. *
  1800. */
  1801. var OutlineWindow = function(editorUi, x, y, w, h)
  1802. {
  1803. var graph = editorUi.editor.graph;
  1804. var div = document.createElement('div');
  1805. div.style.position = 'absolute';
  1806. div.style.width = '100%';
  1807. div.style.height = '100%';
  1808. div.style.overflow = 'hidden';
  1809. this.window = new mxWindow(mxResources.get('outline'), div, x, y, w, h, true, true);
  1810. this.window.minimumSize = new mxRectangle(0, 0, 80, 80);
  1811. this.window.destroyOnClose = false;
  1812. this.window.setMaximizable(false);
  1813. this.window.setResizable(true);
  1814. this.window.setClosable(true);
  1815. this.window.setVisible(true);
  1816. var outline = editorUi.createOutline(this.window);
  1817. editorUi.installResizeHandler(this, true, function()
  1818. {
  1819. outline.destroy();
  1820. });
  1821. this.window.addListener(mxEvent.SHOW, mxUtils.bind(this, function()
  1822. {
  1823. this.window.fit();
  1824. outline.setSuspended(false);
  1825. }));
  1826. this.window.addListener(mxEvent.HIDE, mxUtils.bind(this, function()
  1827. {
  1828. outline.setSuspended(true);
  1829. }));
  1830. this.window.addListener(mxEvent.NORMALIZE, mxUtils.bind(this, function()
  1831. {
  1832. outline.setSuspended(false);
  1833. }));
  1834. this.window.addListener(mxEvent.MINIMIZE, mxUtils.bind(this, function()
  1835. {
  1836. outline.setSuspended(true);
  1837. }));
  1838. outline.init(div);
  1839. mxEvent.addMouseWheelListener(function(evt, up)
  1840. {
  1841. var outlineWheel = false;
  1842. var source = mxEvent.getSource(evt);
  1843. while (source != null)
  1844. {
  1845. if (source == outline.svg)
  1846. {
  1847. outlineWheel = true;
  1848. break;
  1849. }
  1850. source = source.parentNode;
  1851. }
  1852. if (outlineWheel)
  1853. {
  1854. var factor = graph.zoomFactor;
  1855. // Slower zoom for pinch gesture on trackpad
  1856. if (evt.deltaY != null && Math.round(evt.deltaY) != evt.deltaY)
  1857. {
  1858. factor = 1 + (Math.abs(evt.deltaY) / 20) * (factor - 1);
  1859. }
  1860. graph.lazyZoom(up, null, null, factor);
  1861. mxEvent.consume(evt);
  1862. }
  1863. });
  1864. };
  1865. /**
  1866. *
  1867. */
  1868. var LayersWindow = function(editorUi, x, y, w, h)
  1869. {
  1870. var graph = editorUi.editor.graph;
  1871. var div = document.createElement('div');
  1872. div.className = 'geBackground';
  1873. div.style.userSelect = 'none';
  1874. div.style.border = '1px solid whiteSmoke';
  1875. div.style.height = '100%';
  1876. div.style.marginBottom = '10px';
  1877. div.style.overflow = 'auto';
  1878. var tbarHeight = (!EditorUi.compactUi) ? '30px' : '26px';
  1879. var listDiv = document.createElement('div')
  1880. listDiv.className = 'geBackground';
  1881. listDiv.style.position = 'absolute';
  1882. listDiv.style.overflow = 'auto';
  1883. listDiv.style.left = '0px';
  1884. listDiv.style.right = '0px';
  1885. listDiv.style.top = '0px';
  1886. listDiv.style.bottom = (parseInt(tbarHeight) + 7) + 'px';
  1887. div.appendChild(listDiv);
  1888. var dragSource = null;
  1889. var dropIndex = null;
  1890. mxEvent.addListener(div, 'dragover', function(evt)
  1891. {
  1892. evt.dataTransfer.dropEffect = 'move';
  1893. dropIndex = 0;
  1894. evt.stopPropagation();
  1895. evt.preventDefault();
  1896. });
  1897. // Workaround for "no element found" error in FF
  1898. mxEvent.addListener(div, 'drop', function(evt)
  1899. {
  1900. evt.stopPropagation();
  1901. evt.preventDefault();
  1902. });
  1903. var layerCount = null;
  1904. var selectionLayer = null;
  1905. var ldiv = document.createElement('div');
  1906. ldiv.className = 'geToolbarContainer';
  1907. ldiv.style.position = 'absolute';
  1908. ldiv.style.bottom = '0px';
  1909. ldiv.style.left = '0px';
  1910. ldiv.style.right = '0px';
  1911. ldiv.style.height = tbarHeight;
  1912. ldiv.style.overflow = 'hidden';
  1913. ldiv.style.padding = (!EditorUi.compactUi) ? '1px' : '4px 0px 3px 0px';
  1914. ldiv.style.borderWidth = '1px 0px 0px 0px';
  1915. ldiv.style.borderStyle = 'solid';
  1916. ldiv.style.display = 'block';
  1917. ldiv.style.whiteSpace = 'nowrap';
  1918. var link = document.createElement('a');
  1919. link.className = 'geButton';
  1920. var removeLink = link.cloneNode(false);
  1921. var img = document.createElement('img');
  1922. img.className = 'geAdaptiveAsset';
  1923. img.setAttribute('border', '0');
  1924. img.setAttribute('width', '22');
  1925. img.setAttribute('src', Editor.trashImage);
  1926. img.style.opacity = '0.9';
  1927. removeLink.appendChild(img);
  1928. mxEvent.addListener(removeLink, 'click', function(evt)
  1929. {
  1930. if (graph.isEnabled())
  1931. {
  1932. graph.model.beginUpdate();
  1933. try
  1934. {
  1935. var index = graph.model.root.getIndex(selectionLayer);
  1936. graph.removeCells([selectionLayer], false);
  1937. // Creates default layer if no layer exists
  1938. if (graph.model.getChildCount(graph.model.root) == 0)
  1939. {
  1940. graph.model.add(graph.model.root, new mxCell());
  1941. graph.setDefaultParent(null);
  1942. }
  1943. else if (index > 0 && index <= graph.model.getChildCount(graph.model.root))
  1944. {
  1945. graph.setDefaultParent(graph.model.getChildAt(graph.model.root, index - 1));
  1946. }
  1947. else
  1948. {
  1949. graph.setDefaultParent(null);
  1950. }
  1951. }
  1952. finally
  1953. {
  1954. graph.model.endUpdate();
  1955. }
  1956. }
  1957. mxEvent.consume(evt);
  1958. });
  1959. if (!graph.isEnabled())
  1960. {
  1961. removeLink.className = 'geButton mxDisabled';
  1962. }
  1963. ldiv.appendChild(removeLink);
  1964. var insertLink = link.cloneNode();
  1965. insertLink.setAttribute('title', mxUtils.trim(mxResources.get('moveSelectionTo', ['...'])));
  1966. img = img.cloneNode(false);
  1967. img.setAttribute('src', Editor.verticalDotsImage);
  1968. insertLink.appendChild(img);
  1969. mxEvent.addListener(insertLink, 'click', function(evt)
  1970. {
  1971. if (graph.isEnabled() && !graph.isSelectionEmpty())
  1972. {
  1973. var offset = mxUtils.getOffset(insertLink);
  1974. editorUi.showPopupMenu(mxUtils.bind(this, function(menu, parent)
  1975. {
  1976. var layer = graph.getLayerForCells(graph.getSelectionCells());
  1977. for (var i = layerCount - 1; i >= 0; i--)
  1978. {
  1979. (mxUtils.bind(this, function(child)
  1980. {
  1981. var locked = mxUtils.getValue(graph.getCurrentCellStyle(child), 'locked', '0') == '1';
  1982. var item = menu.addItem(graph.convertValueToString(child) ||
  1983. mxResources.get('background'), null, mxUtils.bind(this, function()
  1984. {
  1985. if (!locked)
  1986. {
  1987. graph.moveCells(graph.getSelectionCells(), 0, 0, false, child);
  1988. }
  1989. }), parent, null, null, !locked);
  1990. if (locked)
  1991. {
  1992. menu.addCheckmark(item, Editor.lockedImage);
  1993. }
  1994. else if (child == layer)
  1995. {
  1996. menu.addCheckmark(item, Editor.checkmarkImage);
  1997. }
  1998. }))(graph.model.getChildAt(graph.model.root, i));
  1999. }
  2000. }), offset.x, offset.y + insertLink.offsetHeight, evt);
  2001. }
  2002. });
  2003. ldiv.appendChild(insertLink);
  2004. var dataLink = link.cloneNode(false);
  2005. dataLink.setAttribute('title', mxResources.get('editData'));
  2006. img = img.cloneNode(false);
  2007. img.setAttribute('src', Editor.editImage);
  2008. dataLink.appendChild(img);
  2009. mxEvent.addListener(dataLink, 'click', function(evt)
  2010. {
  2011. if (graph.isEnabled())
  2012. {
  2013. editorUi.showDataDialog(selectionLayer);
  2014. }
  2015. mxEvent.consume(evt);
  2016. });
  2017. if (!graph.isEnabled())
  2018. {
  2019. dataLink.className = 'geButton mxDisabled';
  2020. }
  2021. ldiv.appendChild(dataLink);
  2022. var layerDivs = new mxDictionary();
  2023. var duplicateLink = link.cloneNode(false);
  2024. duplicateLink.setAttribute('title', mxResources.get('duplicate'));
  2025. img = img.cloneNode(false);
  2026. img.setAttribute('src', Editor.duplicateImage);
  2027. duplicateLink.appendChild(img);
  2028. mxEvent.addListener(duplicateLink, 'click', function(evt)
  2029. {
  2030. if (graph.isEnabled())
  2031. {
  2032. var newCell = null;
  2033. graph.model.beginUpdate();
  2034. try
  2035. {
  2036. newCell = graph.cloneCell(selectionLayer);
  2037. graph.cellLabelChanged(newCell, mxResources.get('untitledLayer'));
  2038. newCell.setVisible(true);
  2039. newCell = graph.addCell(newCell, graph.model.root);
  2040. graph.setDefaultParent(newCell);
  2041. }
  2042. finally
  2043. {
  2044. graph.model.endUpdate();
  2045. }
  2046. if (newCell != null && !graph.isCellLocked(newCell))
  2047. {
  2048. graph.selectAll(newCell);
  2049. }
  2050. }
  2051. });
  2052. if (!graph.isEnabled())
  2053. {
  2054. duplicateLink.className = 'geButton mxDisabled';
  2055. }
  2056. ldiv.appendChild(duplicateLink);
  2057. var addLink = link.cloneNode(false);
  2058. addLink.setAttribute('title', mxResources.get('addLayer'));
  2059. img = img.cloneNode(false);
  2060. img.setAttribute('src', Editor.addImage);
  2061. addLink.appendChild(img);
  2062. mxEvent.addListener(addLink, 'click', function(evt)
  2063. {
  2064. if (graph.isEnabled())
  2065. {
  2066. graph.model.beginUpdate();
  2067. var cell
  2068. try
  2069. {
  2070. cell = graph.addCell(new mxCell(mxResources.get('untitledLayer')), graph.model.root);
  2071. graph.setDefaultParent(cell);
  2072. }
  2073. finally
  2074. {
  2075. graph.model.endUpdate();
  2076. }
  2077. renameLayer(cell);
  2078. }
  2079. mxEvent.consume(evt);
  2080. });
  2081. if (!graph.isEnabled())
  2082. {
  2083. addLink.className = 'geButton mxDisabled';
  2084. }
  2085. ldiv.appendChild(addLink);
  2086. div.appendChild(ldiv);
  2087. var dot = document.createElement('span');
  2088. dot.setAttribute('title', mxResources.get('selectionOnly'));
  2089. dot.innerHTML = '&#8226;';
  2090. dot.style.position = 'absolute';
  2091. dot.style.fontWeight = 'bold';
  2092. dot.style.fontSize = '16pt';
  2093. dot.style.right = '2px';
  2094. dot.style.top = '2px';
  2095. function updateLayerDot()
  2096. {
  2097. var div = layerDivs.get(graph.getLayerForCells(graph.getSelectionCells()));
  2098. if (div != null)
  2099. {
  2100. div.appendChild(dot);
  2101. }
  2102. else if (dot.parentNode != null)
  2103. {
  2104. dot.parentNode.removeChild(dot);
  2105. }
  2106. };
  2107. function refresh()
  2108. {
  2109. if (graph.isEnabled())
  2110. {
  2111. removeLink.classList.remove('mxDisabled');
  2112. dataLink.classList.remove('mxDisabled');
  2113. duplicateLink.classList.remove('mxDisabled');;
  2114. addLink.classList.remove('mxDisabled');
  2115. }
  2116. else
  2117. {
  2118. removeLink.classList.add('mxDisabled');
  2119. dataLink.classList.add('mxDisabled');
  2120. duplicateLink.classList.add('mxDisabled');
  2121. addLink.classList.add('mxDisabled');
  2122. }
  2123. layerCount = graph.model.getChildCount(graph.model.root)
  2124. listDiv.innerText = '';
  2125. layerDivs.clear();
  2126. function addLayer(index, label, child, defaultParent)
  2127. {
  2128. var ldiv = document.createElement('div');
  2129. ldiv.className = 'geToolbarContainer';
  2130. layerDivs.put(child, ldiv);
  2131. ldiv.style.overflow = 'hidden';
  2132. ldiv.style.position = 'relative';
  2133. ldiv.style.padding = '4px';
  2134. ldiv.style.height = '22px';
  2135. ldiv.style.display = 'block';
  2136. ldiv.style.backgroundColor = (Editor.isDarkMode()) ?
  2137. Editor.darkColor : 'whiteSmoke';
  2138. ldiv.style.borderWidth = '0px 0px 1px 0px';
  2139. ldiv.style.borderColor = '#c3c3c3';
  2140. ldiv.style.borderStyle = 'solid';
  2141. ldiv.style.whiteSpace = 'nowrap';
  2142. ldiv.setAttribute('title', label +
  2143. ' (' + child.getId() + ')');
  2144. var left = document.createElement('div');
  2145. left.style.display = 'inline-block';
  2146. left.style.width = '100%';
  2147. left.style.textOverflow = 'ellipsis';
  2148. left.style.overflow = 'hidden';
  2149. var span = document.createElement('span');
  2150. mxEvent.addListener(ldiv, 'dragover', function(evt)
  2151. {
  2152. evt.dataTransfer.dropEffect = 'move';
  2153. dropIndex = index;
  2154. evt.stopPropagation();
  2155. evt.preventDefault();
  2156. });
  2157. mxEvent.addListener(ldiv, 'dragstart', function(evt)
  2158. {
  2159. if (span.contentEditable != 'true')
  2160. {
  2161. dragSource = ldiv;
  2162. // Workaround for no DnD on DIV in FF
  2163. if (mxClient.IS_FF)
  2164. {
  2165. // LATER: Check what triggers a parse as XML on this in FF after drop
  2166. evt.dataTransfer.setData('Text', '<layer/>');
  2167. }
  2168. }
  2169. });
  2170. mxEvent.addListener(ldiv, 'dragend', function(evt)
  2171. {
  2172. if (dragSource != null && dropIndex != null)
  2173. {
  2174. graph.addCell(child, graph.model.root, dropIndex);
  2175. }
  2176. dragSource = null;
  2177. dropIndex = null;
  2178. evt.stopPropagation();
  2179. evt.preventDefault();
  2180. });
  2181. var inp = document.createElement('img');
  2182. inp.setAttribute('draggable', 'false');
  2183. inp.setAttribute('align', 'top');
  2184. inp.setAttribute('border', '0');
  2185. inp.className = 'geAdaptiveAsset';
  2186. inp.style.width = '16px';
  2187. inp.style.padding = '0px 6px 0 4px';
  2188. inp.style.marginTop = '2px';
  2189. inp.style.cursor = 'pointer';
  2190. inp.setAttribute('title', mxResources.get(
  2191. graph.model.isVisible(child) ?
  2192. 'hide' : 'show'));
  2193. if (graph.model.isVisible(child))
  2194. {
  2195. inp.setAttribute('src', Editor.visibleImage);
  2196. mxUtils.setOpacity(ldiv, 90);
  2197. }
  2198. else
  2199. {
  2200. inp.setAttribute('src', Editor.hiddenImage);
  2201. mxUtils.setOpacity(ldiv, 40);
  2202. }
  2203. if (!graph.isEnabled())
  2204. {
  2205. mxUtils.setOpacity(inp, 50);
  2206. }
  2207. left.appendChild(inp);
  2208. mxEvent.addListener(inp, 'click', function(evt)
  2209. {
  2210. if (graph.isEnabled())
  2211. {
  2212. graph.model.setVisible(child, !graph.model.isVisible(child));
  2213. }
  2214. mxEvent.consume(evt);
  2215. });
  2216. var btn = document.createElement('img');
  2217. btn.setAttribute('draggable', 'false');
  2218. btn.setAttribute('align', 'top');
  2219. btn.setAttribute('border', '0');
  2220. btn.className = 'geAdaptiveAsset';
  2221. btn.style.width = '16px';
  2222. btn.style.padding = '0px 6px 0 0';
  2223. btn.style.marginTop = '2px';
  2224. btn.setAttribute('title', mxResources.get('lockUnlock'));
  2225. var style = graph.getCurrentCellStyle(child);
  2226. if (mxUtils.getValue(style, 'locked', '0') == '1')
  2227. {
  2228. btn.setAttribute('src', Editor.lockedImage);
  2229. mxUtils.setOpacity(btn, 90);
  2230. ldiv.style.color = 'red';
  2231. }
  2232. else
  2233. {
  2234. btn.setAttribute('src', Editor.unlockedImage);
  2235. mxUtils.setOpacity(btn, 40);
  2236. }
  2237. if (graph.isEnabled())
  2238. {
  2239. btn.style.cursor = 'pointer';
  2240. }
  2241. mxEvent.addListener(btn, 'click', function(evt)
  2242. {
  2243. if (graph.isEnabled())
  2244. {
  2245. var value = null;
  2246. graph.getModel().beginUpdate();
  2247. try
  2248. {
  2249. value = (mxUtils.getValue(style, 'locked', '0') == '1') ? null : '1';
  2250. graph.setCellStyles('locked', value, [child]);
  2251. }
  2252. finally
  2253. {
  2254. graph.getModel().endUpdate();
  2255. }
  2256. if (value == '1')
  2257. {
  2258. graph.removeSelectionCells(graph.getModel().getDescendants(child));
  2259. }
  2260. mxEvent.consume(evt);
  2261. }
  2262. });
  2263. left.appendChild(btn);
  2264. mxUtils.write(span, label);
  2265. span.style.display = 'block';
  2266. span.style.whiteSpace = 'nowrap';
  2267. span.style.overflow = 'hidden';
  2268. span.style.textOverflow = 'ellipsis';
  2269. span.style.position = 'absolute';
  2270. span.style.padding = '2px';
  2271. span.style.left = '52px';
  2272. span.style.right = '8px';
  2273. span.style.top = '6px';
  2274. left.appendChild(span);
  2275. ldiv.appendChild(left);
  2276. if (graph.isEnabled())
  2277. {
  2278. // Fallback if no drag and drop is available
  2279. if (mxClient.IS_TOUCH || mxClient.IS_POINTER ||
  2280. (mxClient.IS_IE && document.documentMode < 10))
  2281. {
  2282. var right = document.createElement('div');
  2283. right.style.display = 'block';
  2284. right.style.textAlign = 'right';
  2285. right.style.whiteSpace = 'nowrap';
  2286. right.style.position = 'absolute';
  2287. right.style.right = '16px';
  2288. right.style.top = '6px';
  2289. // Poor man's change layer order
  2290. if (index > 0)
  2291. {
  2292. var img2 = document.createElement('a');
  2293. img2.setAttribute('title', mxResources.get('toBack'));
  2294. img2.className = 'geButton';
  2295. img2.style.cssFloat = 'none';
  2296. img2.innerHTML = '&#9660;';
  2297. img2.style.width = '14px';
  2298. img2.style.height = '14px';
  2299. img2.style.fontSize = '14px';
  2300. img2.style.margin = '0px';
  2301. img2.style.marginTop = '-1px';
  2302. right.appendChild(img2);
  2303. mxEvent.addListener(img2, 'click', function(evt)
  2304. {
  2305. if (graph.isEnabled())
  2306. {
  2307. graph.addCell(child, graph.model.root, index - 1);
  2308. }
  2309. mxEvent.consume(evt);
  2310. });
  2311. }
  2312. if (index >= 0 && index < layerCount - 1)
  2313. {
  2314. var img1 = document.createElement('a');
  2315. img1.setAttribute('title', mxResources.get('toFront'));
  2316. img1.className = 'geButton';
  2317. img1.style.cssFloat = 'none';
  2318. img1.innerHTML = '&#9650;';
  2319. img1.style.width = '14px';
  2320. img1.style.height = '14px';
  2321. img1.style.fontSize = '14px';
  2322. img1.style.margin = '0px';
  2323. img1.style.marginTop = '-1px';
  2324. right.appendChild(img1);
  2325. mxEvent.addListener(img1, 'click', function(evt)
  2326. {
  2327. if (graph.isEnabled())
  2328. {
  2329. graph.addCell(child, graph.model.root, index + 1);
  2330. }
  2331. mxEvent.consume(evt);
  2332. });
  2333. }
  2334. ldiv.appendChild(right);
  2335. }
  2336. if (mxClient.IS_SVG && (!mxClient.IS_IE || document.documentMode >= 10))
  2337. {
  2338. ldiv.setAttribute('draggable', 'true');
  2339. ldiv.style.cursor = 'move';
  2340. }
  2341. }
  2342. mxEvent.addListener(ldiv, 'dblclick', function(evt)
  2343. {
  2344. var nodeName = mxEvent.getSource(evt).nodeName;
  2345. if (nodeName != 'INPUT' && nodeName != 'IMG' &&
  2346. span.contentEditable != 'true')
  2347. {
  2348. renameLayer(child);
  2349. mxEvent.consume(evt);
  2350. }
  2351. });
  2352. if (graph.getDefaultParent() == child)
  2353. {
  2354. ldiv.style.background = (!Editor.isDarkMode()) ? '#e6eff8' : '#505759';
  2355. ldiv.style.fontWeight = (graph.isEnabled()) ? 'bold' : '';
  2356. selectionLayer = child;
  2357. }
  2358. mxEvent.addListener(ldiv, 'click', function(evt)
  2359. {
  2360. if (graph.isEnabled() && span.contentEditable != 'true')
  2361. {
  2362. graph.setDefaultParent(defaultParent);
  2363. graph.view.setCurrentRoot(null);
  2364. if (mxEvent.isShiftDown(evt))
  2365. {
  2366. graph.setSelectionCells(child.children);
  2367. }
  2368. mxEvent.consume(evt);
  2369. }
  2370. });
  2371. listDiv.appendChild(ldiv);
  2372. };
  2373. // Cannot be moved or deleted
  2374. for (var i = layerCount - 1; i >= 0; i--)
  2375. {
  2376. (mxUtils.bind(this, function(child)
  2377. {
  2378. addLayer(i, graph.convertValueToString(child) ||
  2379. mxResources.get('background'), child, child);
  2380. }))(graph.model.getChildAt(graph.model.root, i));
  2381. }
  2382. var label = graph.convertValueToString(selectionLayer) || mxResources.get('background');
  2383. removeLink.setAttribute('title', mxResources.get('removeIt', [label]));
  2384. duplicateLink.setAttribute('title', mxResources.get('duplicateIt', [label]));
  2385. if (graph.isSelectionEmpty())
  2386. {
  2387. insertLink.className = 'geButton mxDisabled';
  2388. }
  2389. updateLayerDot();
  2390. };
  2391. refresh();
  2392. graph.model.addListener(mxEvent.CHANGE, refresh);
  2393. graph.addListener('defaultParentChanged', refresh);
  2394. editorUi.addListener('lockedChanged', refresh);
  2395. function renameLayer(layer)
  2396. {
  2397. if (graph.isEnabled() && layer != null)
  2398. {
  2399. var div = layerDivs.get(layer);
  2400. if (div != null)
  2401. {
  2402. var spans = div.getElementsByTagName('span');
  2403. if (spans != null && spans.length > 0)
  2404. {
  2405. var span = spans[0];
  2406. var oldValue = mxUtils.getTextContent(span);
  2407. span.style.textOverflow = '';
  2408. span.style.cursor = 'text';
  2409. span.contentEditable = 'true';
  2410. span.focus();
  2411. document.execCommand('selectAll', false, null);
  2412. // Stops drag and drop on parent div
  2413. div.removeAttribute('draggable');
  2414. div.style.cursor = '';
  2415. var stopEditing = function(applyValue)
  2416. {
  2417. if (span.contentEditable == 'true')
  2418. {
  2419. span.contentEditable = 'false';
  2420. var newValue = mxUtils.getTextContent(span);
  2421. if (applyValue && newValue != oldValue)
  2422. {
  2423. var newValue = mxUtils.getTextContent(span);
  2424. if (newValue.length > 0)
  2425. {
  2426. graph.cellLabelChanged(layer, newValue);
  2427. }
  2428. else
  2429. {
  2430. graph.cellLabelChanged(layer, mxResources.get('untitledLayer'));
  2431. }
  2432. }
  2433. else
  2434. {
  2435. refresh();
  2436. }
  2437. }
  2438. };
  2439. mxEvent.addListener(span, 'keydown', function(evt)
  2440. {
  2441. if (evt.keyCode == 13 || evt.keyCode == 27)
  2442. {
  2443. stopEditing(evt.keyCode == 13);
  2444. mxEvent.consume(evt);
  2445. }
  2446. });
  2447. mxEvent.addListener(span, 'blur', function(evt)
  2448. {
  2449. stopEditing(true);
  2450. mxEvent.consume(evt);
  2451. });
  2452. }
  2453. }
  2454. }
  2455. };
  2456. graph.selectionModel.addListener(mxEvent.CHANGE, function()
  2457. {
  2458. if (graph.isSelectionEmpty())
  2459. {
  2460. insertLink.className = 'geButton mxDisabled';
  2461. }
  2462. else
  2463. {
  2464. insertLink.className = 'geButton';
  2465. }
  2466. updateLayerDot();
  2467. });
  2468. this.window = new mxWindow(mxResources.get('layers'), div, x, y, w, h, true, true);
  2469. this.window.minimumSize = new mxRectangle(0, 0, 150, 120);
  2470. this.window.destroyOnClose = false;
  2471. this.window.setMaximizable(false);
  2472. this.window.setResizable(true);
  2473. this.window.setClosable(true);
  2474. this.window.setVisible(true);
  2475. this.init = function()
  2476. {
  2477. listDiv.scrollTop = listDiv.scrollHeight - listDiv.clientHeight;
  2478. };
  2479. this.window.addListener(mxEvent.SHOW, mxUtils.bind(this, function()
  2480. {
  2481. this.window.fit();
  2482. }));
  2483. // Make refresh available via instance
  2484. this.refreshLayers = refresh;
  2485. editorUi.installResizeHandler(this, true);
  2486. };