cheditor.js 309 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969
  1. // ================================================================
  2. // CHEditor 5.1.9.4
  3. // ----------------------------------------------------------------
  4. // Homepage: http://www.chcode.com
  5. // EMail: support@chcode.com
  6. // Copyright (c) 1997-2019 CHSOFT
  7. // ================================================================
  8. var GB = {
  9. colors: ['#000000', '#313131', '#434343', '#535353', '#666666', '#999999', '#a0a0a0', '#b5b5b5', '#c0c0c0', '#dcdcdc', '#eeeeee', '#ffffff',
  10. '#ff0000', '#ff8000', '#ffff00', '#80ff00', '#00ff00', '#00ff99', '#00ffff', '#0080ff', '#0000ff', '#7f00ff', '#ff00ff', '#ff007f',
  11. '#ffcccc', '#ffe5cc', '#ffffcc', '#e5ffcc', '#ccffcc', '#ccffe5', '#ccffff', '#cce5ff', '#ccccff', '#e5ccff', '#ffccff', '#ffcce5',
  12. '#ff9999', '#ffcc99', '#ffff99', '#ccff99', '#99ff99', '#99ffcc', '#99ffff', '#99ccff', '#9999ff', '#cc99ff', '#ff99ff', '#ff99cc',
  13. '#ff6666', '#ffb266', '#ffff66', '#b2ff66', '#66ff66', '#66ffb2', '#66ffff', '#66b2ff', '#6666ff', '#b266ff', '#ff66ff', '#ff66b2',
  14. '#ff3333', '#ff9933', '#ffff33', '#99ff33', '#33ff33', '#33ff99', '#33ffff', '#3399ff', '#3333ff', '#9933ff', '#ff33ff', '#ff3399',
  15. '#cc0000', '#cc6600', '#cccc00', '#66cc00', '#00cc00', '#00cc66', '#00cccc', '#0066cc', '#0000cc', '#6600cc', '#cc00cc', '#cc0066',
  16. '#990000', '#994c00', '#999900', '#4c9900', '#009900', '#00994c', '#009999', '#004c99', '#000099', '#4c0099', '#990099', '#99004c',
  17. '#660000', '#663300', '#666600', '#336600', '#006600', '#006633', '#006666', '#003366', '#000066', '#330066', '#660066', '#660033'],
  18. offElementTags: {
  19. button: 1, embed: 1, fieldset: 1, form: 1, hr: 1, img: 1, input: 1, object: 1, select: 1, table: 1, textarea: 1
  20. },
  21. selfClosingTags: {
  22. area: 1, base: 1, br: 1, col: 1, command: 1, embed: 1, hr: 1, img: 1, input: 1, keygen: 1, link: 1, meta: 1,
  23. param: 1, source: 1, track: 1, wbr: 1
  24. },
  25. textFormatTags: {
  26. a: 1, addr: 1, acronym: 1, b: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1, dfn: 1, em: 1, font: 1, i: 1, ins: 1, kbd: 1,
  27. q: 1, samp: 1, small: 1, strike: 1, strong: 1, sub: 1, sup: 1, time: 1, tt: 1, u: 1, 'var': 1, span: 1
  28. },
  29. textFormatBlockTags: {
  30. address: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, p: 1, pre: 1, code: 1, section: 1, aside: 1, article: 1, figcaption: 1
  31. },
  32. newLineBeforeTags: {
  33. address: 1, article: 1, aside: 1, audio: 1, blockquote: 1, body: 1, canvas: 1, code: 1, comment: 1, dd: 1, div: 1,
  34. dl: 1, fieldset: 1, figcaption: 1, figure: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, head: 1,
  35. header: 1, hggroup: 1, hr: 1, li: 1, noscript: 1, ol: 1, output: 1, p: 1, pre: 1, script: 1, section: 1, table: 1,
  36. tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, title: 1, tr: 1, ul: 1, video: 1
  37. },
  38. lineHeightBlockTags: {
  39. address: 1, article: 1, aside: 1, blockquote: 1, code: 1, dd: 1, div: 1, dt: 1, figcaption: 1, figure: 1,
  40. h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, li: 1, p: 1, pre: 1, section: 1, td: 1, th: 1
  41. },
  42. listTags: { dd: 1, dt: 1, li: 1 },
  43. lineBreakTags: { address: 1, article: 1, aside: 1, dd: 1, div: 1, dt: 1, figcaption: 1, li: 1, p: 1, section: 1 },
  44. doctype: '<!DOCTYPE html>',
  45. popupWindow: {
  46. ColorPicker: { tmpl: 'color_picker.html', width: 420, title: '색상 선택' },
  47. Embed: { tmpl: 'media.html', width: 430, title: '미디어' },
  48. EmotionIcon: { tmpl: 'icon.html', width: 300, title: '표정 아이콘' },
  49. FlashMovie: { tmpl: 'flash.html', width: 584, title: '플래쉬 동영상' },
  50. GoogleMap: { tmpl: 'google_map.html', width: 538, title: '구글 지도' },
  51. ImageUpload: { tmpl: 'image.html', width: 700, title: '내 PC 사진 넣기' },
  52. ImageUrl: { tmpl: 'image_url.html', width: 350, title: '웹 사진 넣기' },
  53. Layout: { tmpl: 'layout.html', width: 430, title: '레이아웃' },
  54. Link: { tmpl: 'link.html', width: 350, title: '하이퍼링크' },
  55. ModifyTable: { tmpl: 'table_modify.html', width: 430, title: '표 고치기' },
  56. Symbol: { tmpl: 'symbol.html', width: 450, title: '특수 문자' },
  57. Table: { tmpl: 'table.html', width: 430, title: '표 만들기' }
  58. },
  59. fontName: {
  60. kr: ['맑은 고딕', '돋움', '굴림', '바탕', '궁서'],
  61. en: ['Arial', 'Comic Sans MS', 'Courier New', 'Georgia', 'HeadLineA', 'Impact', 'Tahoma', 'Times New Roman', 'Verdana']
  62. },
  63. fontStyle: {
  64. FontSize: 'font-size', FontName: 'font-family', ForeColor: 'color', BackColor: 'background-color'
  65. },
  66. textAlign: {
  67. JustifyLeft: '', JustifyCenter: 'center', JustifyRight: 'right', JustifyFull: 'justify'
  68. },
  69. listStyle: {
  70. ordered: {
  71. decimal: '숫자', 'lower-alpha': '영문 소문자', 'upper-alpha': '영문 대문자', 'lower-roman': '로마 소문자', 'upper-roman': '로마 대문자'
  72. },
  73. unOrdered: { desc: '동그라미', circle: '빈 원', square: '사각형' }
  74. },
  75. fontSize: {
  76. pt: [7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36],
  77. px: [9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72]
  78. },
  79. formatBlock: {
  80. P: '일반 텍스트',
  81. H1: '제목 1',
  82. H2: '제목 2',
  83. H3: '제목 3',
  84. H4: '제목 4',
  85. H5: '제목 5',
  86. H6: '제목 6',
  87. ADDRESS: 'Address',
  88. DIV: 'DIV',
  89. PRE: 'Preformatted (PRE)'
  90. },
  91. lineHeight: {
  92. '한 줄 간격': 1, '1.15': 1.15, '1.5': 1.5, '1.7': 1.7, '1.8': 1.8, '두 줄 간격': 2
  93. },
  94. textBlock: [
  95. ['1px #dedfdf solid', '#f7f7f7'],
  96. ['1px #aee8e8 solid', '#bfffff'],
  97. ['1px #d3bceb solid', '#e6ccff'],
  98. ['1px #e8e88b solid', '#ffff99'],
  99. ['1px #c3e89e solid', '#d6ffad'],
  100. ['1px #e8c8b7 solid', '#ffdcc9'],
  101. ['1px #666666 dashed', '#ffffff'],
  102. ['1px #d4d4d4 solid', '#ffffff'],
  103. ['1px #cccccc inset', '#f7f7f7']
  104. ],
  105. node: {
  106. element: 1, attribute: 2, text: 3, cdata_section: 4, entity_reference: 5, entity: 6,
  107. processing_instruction: 7, comment: 8, document: 9, document_type: 10, document_fragment: 11,
  108. notation: 12
  109. },
  110. selection: { none: 1, text: 2, element: 3 },
  111. readyState: { 0: 'uninitialized', 1: 'loading', 2: 'loaded', 3: 'interactive', 4: 'complete' },
  112. dragWindow: null,
  113. colorDropper: null,
  114. readyEditor: 0,
  115. browser: {}
  116. };
  117. function isUndefined(obj) {
  118. return obj === void (0); // obj === undefined;
  119. }
  120. function detechBrowser() {
  121. function detect(ua) {
  122. var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase(),
  123. likeAndroid = /like android/i.test(ua),
  124. android = !likeAndroid && /android/i.test(ua),
  125. versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i),
  126. tablet = /tablet/i.test(ua),
  127. mobile = !tablet && /[^\-]mobi/i.test(ua),
  128. result,
  129. osVersion = '',
  130. osMajorVersion,
  131. osname,
  132. app;
  133. function getFirstMatch(regex) {
  134. var match = ua.match(regex);
  135. return (match && match.length > 1 && match[1]) || '';
  136. }
  137. if (/opera|opr/i.test(ua)) {
  138. result = {
  139. name: 'Opera', opera: true,
  140. version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)
  141. };
  142. } else if (/windows phone/i.test(ua)) {
  143. result = {
  144. name: 'Windows Phone', windowsphone: true, msie: true,
  145. version: getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
  146. };
  147. } else if (/msie|trident/i.test(ua)) {
  148. result = {
  149. name: 'Internet Explorer', msie: true, version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i)
  150. };
  151. } else if (/edge/i.test(ua)) {
  152. result = {
  153. name: 'edge', edge: true, version: getFirstMatch(/(?:edge)\/(\d+(\.\d+)?)/i)
  154. };
  155. } else if (/chrome|crios|crmo/i.test(ua)) {
  156. result = {
  157. name: 'Chrome', chrome: true, version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
  158. };
  159. } else if (iosdevice) {
  160. result = {
  161. name: iosdevice === 'iphone' ? 'iPhone' : iosdevice === 'ipad' ? 'iPad' : 'iPod'
  162. };
  163. if (versionIdentifier) {
  164. result.version = versionIdentifier;
  165. }
  166. } else if (/firefox|iceweasel/i.test(ua)) {
  167. result = {
  168. name: 'Firefox', firefox: true,
  169. version: getFirstMatch(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i)
  170. };
  171. if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) {
  172. result.firefoxos = true;
  173. }
  174. } else if (/silk/i.test(ua)) {
  175. result = {
  176. name: 'Amazon Silk', silk: true, version: getFirstMatch(/silk\/(\d+(\.\d+)?)/i)
  177. };
  178. } else if (android) {
  179. result = { name: 'Android', version: versionIdentifier };
  180. } else if (/phantom/i.test(ua)) {
  181. result = {
  182. name: 'PhantomJS', phantom: true, version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i)
  183. };
  184. } else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) {
  185. result = {
  186. name: 'BlackBerry', blackberry: true,
  187. version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i)
  188. };
  189. } else if (/(web|hpw)os/i.test(ua)) {
  190. result = {
  191. name: 'WebOS', webos: true,
  192. version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)
  193. };
  194. if (/touchpad\//i.test(ua)) {
  195. result.touchpad = true;
  196. }
  197. } else if (/safari/i.test(ua)) {
  198. result = {
  199. name: 'Safari', safari: true, version: versionIdentifier
  200. };
  201. } else {
  202. result = {};
  203. }
  204. if (/(apple)?webkit/i.test(ua)) {
  205. result.name = result.name || 'Webkit';
  206. result.webkit = true;
  207. if (!result.version && versionIdentifier) {
  208. result.version = versionIdentifier;
  209. }
  210. } else if (!result.opera && /gecko\//i.test(ua)) {
  211. result.gecko = true;
  212. result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i);
  213. result.name = result.name || 'Gecko';
  214. }
  215. if (android || result.silk) {
  216. result.android = true;
  217. } else if (iosdevice) {
  218. result[iosdevice] = true;
  219. result.ios = true;
  220. }
  221. if (iosdevice) {
  222. osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i);
  223. osVersion = osVersion.replace(/[_\s]/g, '.');
  224. } else if (android) {
  225. osVersion = getFirstMatch(/android[ \/\-](\d+(\.\d+)*)/i);
  226. } else if (result.windowsphone) {
  227. osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
  228. } else if (result.webos) {
  229. osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i);
  230. } else if (result.blackberry) {
  231. osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i);
  232. }
  233. if (osVersion) {
  234. result.osversion = osVersion;
  235. }
  236. osMajorVersion = osVersion.split('.')[0];
  237. if (tablet || iosdevice === 'ipad' ||
  238. (android && (osMajorVersion === 3 || (osMajorVersion === 4 && !mobile))) ||
  239. result.silk) {
  240. result.tablet = true;
  241. } else if (mobile || iosdevice === 'iphone' || iosdevice === 'ipod' || android ||
  242. result.blackberry || result.webos) {
  243. result.mobile = true;
  244. }
  245. if (result.edge ||
  246. (result.msie && result.version >= 10) ||
  247. (result.chrome && result.version >= 20) ||
  248. (result.firefox && result.version >= 20.0) ||
  249. (result.safari && result.version >= 6) ||
  250. (result.opera && result.version >= 10.0) ||
  251. (result.ios && result.osversion && result.osversion.split('.')[0] >= 6) ||
  252. (result.blackberry && result.version >= 10.1)) {
  253. result.a = true;
  254. } else if ((result.msie && result.version < 10) ||
  255. (result.chrome && result.version < 20) ||
  256. (result.firefox && result.version < 20.0) ||
  257. (result.safari && result.version < 6) ||
  258. (result.opera && result.version < 10.0) ||
  259. (result.ios && result.osversion && result.osversion.split('.')[0] < 6)) {
  260. result.c = true;
  261. } else {
  262. result.x = true;
  263. }
  264. osname = '';
  265. if (/windows/i.test(ua)) {
  266. osname = 'Windows';
  267. } else if (/mac/i.test(ua)) {
  268. osname = 'MacOS';
  269. } else if (/x11/i.test(ua)) {
  270. osname = 'UNIX';
  271. } else if (/linux/i.test(ua)) {
  272. osname = 'Linux';
  273. } else if (/sunos/i.test(ua)) {
  274. osname = 'Solaris';
  275. } else {
  276. osname = 'Unknown OS';
  277. }
  278. result.osname = osname;
  279. if (osname === 'Windows') {
  280. app = getFirstMatch(/(Windows NT\s(\d+)\.(\d+))/i);
  281. switch (app) {
  282. case 'Windows NT 5.1': result.os = 'Windows XP'; break;
  283. case 'Windows NT 5.2': result.os = 'Windows 2003'; break;
  284. case 'Windows NT 6.0': result.os = 'Windows Vista'; break;
  285. case 'Windows NT 6.1': result.os = 'Windows 7'; break;
  286. case 'Windows NT 6.2': result.os = 'Windows 8'; break;
  287. case 'Windows NT 6.3': result.os = 'Windows 8.1'; break;
  288. case 'Windows NT 10.0': result.os = 'Windows 10'; break;
  289. default: result.os = app;
  290. }
  291. }
  292. if (result.msie) {
  293. if (result.version > 10) {
  294. result.msie_a = true;
  295. result.msie_bogus = true;
  296. } else if (result.version > 8) {
  297. result.msie_b = true;
  298. result.msie_bogus = false;
  299. } else {
  300. result.msie_c = true;
  301. result.msie_bogus = (result.os === 'Windows XP');
  302. }
  303. }
  304. return result;
  305. }
  306. return detect(!isUndefined(navigator) ? navigator.userAgent : null);
  307. }
  308. function URI(uri) {
  309. this.scheme = null;
  310. this.authority = null;
  311. this.path = '';
  312. this.query = null;
  313. this.fragment = null;
  314. this.parseUri = function (uri) {
  315. var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.\-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
  316. this.scheme = m[3] ? m[2] : null;
  317. this.authority = m[5] ? m[6] : null;
  318. this.path = m[7];
  319. this.query = m[9] ? m[10] : null;
  320. this.fragment = m[12] ? m[13] : null;
  321. return this;
  322. };
  323. this.azToString = function () {
  324. var result = '';
  325. if (this.scheme !== null) {
  326. result = result + this.scheme + ':';
  327. }
  328. if (this.authority !== null) {
  329. result = result + '//' + this.authority;
  330. }
  331. if (this.path !== null) {
  332. result = result + this.path;
  333. }
  334. if (this.query !== null) {
  335. result = result + '?' + this.query;
  336. }
  337. if (this.fragment !== null) {
  338. result = result + '#' + this.fragment;
  339. }
  340. return result;
  341. };
  342. this.toAbsolute = function (location) {
  343. var baseUri = new URI(location),
  344. URIAbs = this,
  345. target = new URI(),
  346. removeDotSegments = function (path) {
  347. var result = '', rm;
  348. while (path) {
  349. if (path.substr(0, 3) === '../' || path.substr(0, 2) === './') {
  350. path = path.replace(/^\.+/, '').substr(1);
  351. } else if (path.substr(0, 3) === '/./' || path === '/.') {
  352. path = '/' + path.substr(3);
  353. } else if (path.substr(0, 4) === '/../' || path === '/..') {
  354. path = '/' + path.substr(4);
  355. result = result.replace(/\/?[^\/]*$/, '');
  356. } else if (path === '.' || path === '..') {
  357. path = '';
  358. } else {
  359. rm = path.match(/^\/?[^\/]*/)[0];
  360. path = path.substr(rm.length);
  361. result = result + rm;
  362. }
  363. }
  364. return result;
  365. };
  366. if (baseUri.scheme === null) {
  367. return false;
  368. }
  369. if (URIAbs.scheme !== null && URIAbs.scheme.toLowerCase() === baseUri.scheme.toLowerCase()) {
  370. URIAbs.scheme = null;
  371. }
  372. if (URIAbs.scheme !== null) {
  373. target.scheme = URIAbs.scheme;
  374. target.authority = URIAbs.authority;
  375. target.path = removeDotSegments(URIAbs.path);
  376. target.query = URIAbs.query;
  377. } else {
  378. if (URIAbs.authority !== null) {
  379. target.authority = URIAbs.authority;
  380. target.path = removeDotSegments(URIAbs.path);
  381. target.query = URIAbs.query;
  382. } else {
  383. if (URIAbs.path === '') {
  384. target.path = baseUri.path;
  385. target.query = URIAbs.query || baseUri.query;
  386. } else {
  387. if (URIAbs.path.substr(0, 1) === '/') {
  388. target.path = removeDotSegments(URIAbs.path);
  389. } else {
  390. if (baseUri.authority !== null && baseUri.path === '') {
  391. target.path = '/' + URIAbs.path;
  392. } else {
  393. target.path = baseUri.path.replace(/[^\/]+$/, '') + URIAbs.path;
  394. }
  395. target.path = removeDotSegments(target.path);
  396. }
  397. target.query = URIAbs.query;
  398. }
  399. target.authority = baseUri.authority;
  400. }
  401. target.scheme = baseUri.scheme;
  402. }
  403. target.fragment = URIAbs.fragment;
  404. return target;
  405. };
  406. if (uri) {
  407. this.parseUri(uri);
  408. }
  409. }
  410. function setConfig() {
  411. var config = {
  412. allowedOnEvent: true,
  413. colorToHex: true,
  414. docTitle: '내 문서',
  415. editAreaMargin: '5px 10px',
  416. editorBgColor: '#fff',
  417. editorFontColor: '#000',
  418. editorFontName: '"맑은 고딕", "Malgun Gothic", gulim',
  419. editorFontSize: '12px',
  420. editorHeight: '300px',
  421. editorPath: null,
  422. editorWidth: '100%',
  423. exceptedElements: { script: true, style: true, iframe: false },
  424. fontSizeValue: 'px', // [pt, px]
  425. fullHTMLSource: false,
  426. imgBlockMargin: '5px 0px',
  427. imgCaptionFigure: 'border: 1px #ccc solid; background-color: #f0f0f0; margin: 0',
  428. imgCaptionText: 'margin: 5px 5px; text-align: left; line-height: 17px',
  429. imgCaptionWrapper: '',
  430. imgDefaultAlign: 'left', // [left, center, right]
  431. imgJpegQuality: 0.92, // JPEG 사진의 퀄리티 값, 최대값 1
  432. imgMaxWidth: 800, // 사진 최대 가로 크기, 이 크기 보다 크면 리사이징 처리
  433. imgResizeMinLimit: 32, // 사진 리사이징의 사용자 직접 입력 값이 이 값 보다 작으면, 이 값으로 설정
  434. imgResizeSelected: 800, // 사진 리사이징의 선택 입력 폼의 기본 선택 값
  435. imgResizeValue: [120, 240, 320, 640, 800, -1], // -1 = 사용자 직접 입력
  436. imgSetAttrAlt: true,
  437. imgSetAttrWidth: 1, // -1 = (width="100%"; height="auto"), 0 = 설정 안함, 1 = 기본값
  438. imgUploadNumber: 12,
  439. imgUploadSortName: false,
  440. imgWaterMarkAlpha: 1, // 워터마크 불투명도 (최대값 1)
  441. imgWaterMarkUrl: '', // 워터마크 이미지 URL (예: 'http://udomain.com/cheditor/icons/watermark.png')
  442. includeHostname: true,
  443. lineHeight: 1.7,
  444. linkTarget: '_blank',
  445. makeThumbnail: false, // 사진의 썸네일 이미지 생성, 가로 크기는 thumbnailWidth 값, 세로는 자동 계산
  446. paragraphCss: false, // true = <p style='margin:0'></p>, false = <p></p>
  447. removeIndent: false,
  448. showTagPath: false,
  449. tabIndent: 3,
  450. tabIndex: 0,
  451. thumbnailWidth: 120,
  452. // 버튼 사용 유무
  453. useSource: true,
  454. usePreview: true,
  455. usePrint: true,
  456. useNewDocument: true,
  457. useUndo: true,
  458. useRedo: true,
  459. useCopy: true,
  460. useCut: true,
  461. usePaste: true,
  462. usePasteFromWord: true,
  463. useSelectAll: true,
  464. useStrikethrough: true,
  465. useUnderline: true,
  466. useItalic: true,
  467. useSuperscript: false,
  468. useSubscript: false,
  469. useJustifyLeft: true,
  470. useJustifyCenter: true,
  471. useJustifyRight: true,
  472. useJustifyFull: true,
  473. useBold: true,
  474. useOrderedList: true,
  475. useUnOrderedList: true,
  476. useOutdent: true,
  477. useIndent: true,
  478. useFontName: true,
  479. useFormatBlock: true,
  480. useFontSize: true,
  481. useLineHeight: true,
  482. useBackColor: true,
  483. useForeColor: true,
  484. useRemoveFormat: true,
  485. useClearTag: true,
  486. useSymbol: true,
  487. useLink: true,
  488. useUnLink: true,
  489. useFlash: true,
  490. useMedia: false,
  491. useImage: true,
  492. useImageUrl: false,
  493. useSmileyIcon: true,
  494. useHR: true,
  495. useTable: true,
  496. useModifyTable: true,
  497. useMap: true,
  498. useTextBlock: true,
  499. useFullScreen: true,
  500. usePageBreak: false
  501. },
  502. base, elem, i, editorUri, locationAbs;
  503. if (config.editorPath === null) {
  504. base = location.href;
  505. elem = document.getElementsByTagName('base');
  506. for (i = 0; i < elem.length; i++) {
  507. if (elem[i].href) {
  508. base = elem[i].href;
  509. }
  510. }
  511. elem = document.getElementsByTagName('script');
  512. for (i = 0; i < elem.length; i++) {
  513. if (elem[i].src) {
  514. editorUri = new URI(elem[i].src);
  515. if (/\/cheditor\.js$/.test(editorUri.path)) {
  516. locationAbs = editorUri.toAbsolute(base).azToString();
  517. delete locationAbs.query;
  518. delete locationAbs.fragment;
  519. config.editorPath = locationAbs.replace(/[^\/]+$/, '');
  520. }
  521. }
  522. }
  523. if (config.editorPath === null) {
  524. throw 'CHEditor 경로가 바르지 않습니다.\nmyeditor.config.editorPath를 설정하여 주십시오.';
  525. }
  526. }
  527. this.storedSelections = [];
  528. this.keyPressStoredSelections = [];
  529. this.images = [];
  530. this.editImages = {};
  531. this.cheditor = {};
  532. this.toolbar = {};
  533. this.pulldown = {};
  534. this.currentRS = {};
  535. this.resizeEditor = {};
  536. this.setFullScreenMode = false;
  537. this.modalElementZIndex = 1001;
  538. this.config = config;
  539. this.templateFile = 'template.xml';
  540. this.templatePath = config.editorPath + this.templateFile;
  541. this.W3CRange = !(this.undefined(window.getSelection));
  542. this.inputForm = 'textAreaId';
  543. this.range = null;
  544. this.tempTimer = null;
  545. this.cheditor.tabSpaces = '';
  546. this.cheditor.modifyState = false;
  547. this.cheditor.tabSpaces = new Array(this.config.tabIndent + 1).join(' ');
  548. }
  549. function cheditor() {
  550. this.toType = (function (global) {
  551. var toString = cheditor.prototype.toString,
  552. re = /^.*\s(\w+).*$/;
  553. return function (obj) {
  554. if (obj === global) {
  555. return 'global';
  556. }
  557. return toString.call(obj).replace(re, '$1').toLowerCase();
  558. };
  559. }(this));
  560. this.undefined = isUndefined;
  561. GB.browser = this.browser = detechBrowser();
  562. if (this.undefined(document.execCommand)) {
  563. alert('현재 브라우저에서 CHEditor를 실행할 수 없습니다.');
  564. return null;
  565. }
  566. if (this.browser.msie && this.browser.version < 7) {
  567. alert('CHEditor는 Internet Explorer 7 이하 버전은 지원하지 않습니다.');
  568. return null;
  569. }
  570. try {
  571. setConfig.call(this);
  572. this.cheditor.id = (this.undefined(GB.readyEditor)) ? 1 : GB.readyEditor++;
  573. } catch (e) {
  574. alert(e.toString());
  575. return null;
  576. }
  577. return this;
  578. }
  579. cheditor.prototype = {
  580. //----------------------------------------------------------------
  581. resetData: function () {
  582. if (GB.browser.msie) {
  583. if (this.undefined(this.cheditor.editArea.onreadystatechange)) {
  584. GB.browser.version = 11;
  585. }
  586. GB.browser.msie_bogus = (GB.browser.version < 8 || GB.browser.version > 10);
  587. document.execCommand('BackgroundImageCache', false, true);
  588. }
  589. this.resetEditArea();
  590. },
  591. appendContents: function (contents) {
  592. var div = this.doc.createElement('div');
  593. this.editAreaFocus();
  594. div.innerHTML = String(this.trimSpace(contents));
  595. while (div.hasChildNodes()) {
  596. this.doc.body.appendChild(div.firstChild);
  597. }
  598. this.editAreaFocus();
  599. },
  600. insertContents: function (contents) {
  601. this.editAreaFocus();
  602. this.doCmdPaste(String(this.trimSpace(contents)));
  603. },
  604. replaceContents: function (contents) {
  605. this.editAreaFocus();
  606. this.doc.body.innerHTML = '';
  607. this.loadContents(contents);
  608. this.editAreaFocus();
  609. },
  610. loadContents: function (contents) {
  611. if (typeof contents === 'string') {
  612. contents = this.trimSpace(contents);
  613. if (contents) {
  614. this.cheditor.editArea.style.visibility = 'hidden';
  615. this.doc.body.innerHTML = contents;
  616. this.cheditor.editArea.style.visibility = 'visible';
  617. }
  618. }
  619. },
  620. setFolderPath: function () {
  621. if (this.config.editorPath.charAt(this.config.editorPath.length - 1) !== '/') {
  622. this.config.editorPath += '/';
  623. }
  624. this.config.iconPath = this.config.editorPath + 'icons/';
  625. this.config.cssPath = this.config.editorPath + 'css/';
  626. this.config.popupPath = this.config.editorPath + 'popup/';
  627. },
  628. checkInputForm: function () {
  629. var textarea = document.getElementById(this.inputForm);
  630. if (!textarea) {
  631. throw 'ID가 "' + this.inputForm + '"인 textarea 개체를 찾을 수 없습니다.';
  632. }
  633. textarea.style.display = 'none';
  634. this.cheditor.textarea = textarea;
  635. },
  636. setDesignMode: function (designMode, doc) {
  637. var mode = designMode ? 'on' : 'off';
  638. doc = doc || this.doc;
  639. if (GB.browser.msie) {
  640. if (doc.body.contentEditable !== designMode) {
  641. doc.body.contentEditable = designMode;
  642. }
  643. return;
  644. }
  645. if (doc.designMode !== mode) {
  646. doc.designMode = mode;
  647. }
  648. },
  649. openDoc: function (doc, contents) {
  650. var html = '<html>' +
  651. '<head><title>' + this.config.docTitle + '</title>' +
  652. '<style></style></head><body>';
  653. doc.open();
  654. if (typeof contents === 'string') {
  655. html += this.trimSpace(contents);
  656. }
  657. html += '</body></html>';
  658. doc.write(html);
  659. doc.close();
  660. },
  661. getWindowHandle: function (iframeObj) {
  662. var iframeWin;
  663. if (iframeObj.contentWindow) {
  664. iframeWin = iframeObj.contentWindow;
  665. } else {
  666. throw '현재 브라우저에서 에디터를 실행할 수 없습니다.';
  667. }
  668. return iframeWin;
  669. },
  670. resetDoc: function () {
  671. if (this.undefined(this.cheditor.editArea)) {
  672. return false;
  673. }
  674. try {
  675. this.editArea = this.getWindowHandle(this.cheditor.editArea);
  676. this.doc = GB.browser.msie ? this.editArea.document : this.cheditor.editArea.contentDocument;
  677. this.resetData();
  678. return true;
  679. } catch (e) {
  680. alert(e.toString());
  681. return false;
  682. }
  683. },
  684. resetEditArea: function () {
  685. this.openDoc(this.doc, this.cheditor.textarea.value);
  686. this.setDocumentProp();
  687. },
  688. resetDocumentBody: function () {
  689. this.doc.body.parentNode.replaceChild(this.doc.createElement('body'), this.doc.body);
  690. this.setDocumentBodyProp();
  691. },
  692. setDocumentBodyProp: function () {
  693. this.doc.body.setAttribute('spellcheck', 'false');
  694. this.doc.body.setAttribute('hidefocus', '');
  695. },
  696. setDocumentProp: function () {
  697. var oSheet,
  698. bodyCss = 'font-size:' + this.config.editorFontSize +
  699. '; font-family:' + this.config.editorFontName +
  700. '; color:' + this.config.editorFontColor +
  701. '; margin:' + this.config.editAreaMargin +
  702. '; line-height:' + this.config.lineHeight,
  703. tableCss = 'font-size:' + this.config.editorFontSize + '; line-height:' + this.config.lineHeight,
  704. self = this;
  705. this.setDefaultCss({ css: 'editarea.css', doc: this.doc });
  706. oSheet = this.doc.styleSheets[0];
  707. if (!this.W3CRange) {
  708. oSheet.addRule('body', bodyCss);
  709. oSheet.addRule('table', tableCss);
  710. } else {
  711. oSheet.insertRule('body {' + bodyCss + '}', 0);
  712. oSheet.insertRule('table {' + tableCss + '}', 1);
  713. }
  714. this.setDocumentBodyProp();
  715. this.cheditor.bogusSpacerName = 'ch_bogus_spacer';
  716. this.addEvent(this.doc, 'paste', function (event) {
  717. self.handlePaste(event);
  718. });
  719. if (!GB.browser.msie) {
  720. this.doc.execCommand('defaultParagraphSeparator', false, 'p');
  721. }
  722. this.setDesignMode(true);
  723. this.initDefaultParagraphSeparator();
  724. },
  725. initDefaultParagraphSeparator: function () {
  726. var p = this.doc.createElement('p'), br;
  727. if (this.doc.body.firstChild && this.doc.body.firstChild.nodeName.toLowerCase() === 'br') {
  728. this.doc.body.removeChild(this.doc.body.firstChild);
  729. }
  730. if (this.W3CRange) {
  731. if (!this.doc.body.hasChildNodes()) {
  732. this.doc.body.appendChild(p);
  733. if (!GB.browser.msie && !GB.browser.edge) {
  734. br = this.doc.createElement('br');
  735. br.className = this.cheditor.bogusSpacerName;
  736. p.appendChild(br);
  737. this.placeCaretAt(p, false);
  738. } else {
  739. this.placeCaretAt(p, false);
  740. }
  741. }
  742. } else {
  743. this.doc.body.appendChild(p);
  744. this.placeCaretAt(p, false);
  745. }
  746. },
  747. handleBeforePaste: function () {
  748. var range = this.getRange(), commonAncestorContainer, startOffset, wrapper;
  749. this.backupRange();
  750. if (!range.collapsed) {
  751. range.deleteContents();
  752. range = this.getRange();
  753. }
  754. commonAncestorContainer = range.commonAncestorContainer;
  755. startOffset = range.startOffset;
  756. wrapper = this.doc.createElement('div');
  757. if (startOffset < 1 && commonAncestorContainer.nodeType === GB.node.text) {
  758. commonAncestorContainer.parentNode.insertBefore(wrapper, commonAncestorContainer);
  759. } else {
  760. range.insertNode(wrapper);
  761. }
  762. this.placeCaretAt(wrapper, false);
  763. return wrapper;
  764. },
  765. handlePaste: function (ev) {
  766. var text, clip, elem, wrapper, pNode, space = [], div, self = this;
  767. if (this.cheditor.mode === 'preview') {
  768. return;
  769. }
  770. if (this.cheditor.paste !== 'text' && this.cheditor.mode === 'rich' && this.W3CRange) {
  771. wrapper = this.handleBeforePaste();
  772. setTimeout(function () {
  773. if (wrapper) {
  774. if (wrapper.hasChildNodes()) {
  775. text = wrapper.innerHTML;
  776. text = text.replace(/[\r\n]/g, '\u00a0');
  777. text = text.replace(/<font\s?([^>]+)>(\s+|&nbsp;+)<\/font>/gi, '\u00a0');
  778. text = text.replace(/<span\s?([^>]+)>(\s+|&nbsp;+)<\/span>/gi, '\u00a0');
  779. text = text.replace(/<\/?(font)\s?([^>]+)?>/gi, '');
  780. text = text.replace(/<strong>([\s&nbsp;]+)<\/strong>/gi, '\u00a0');
  781. text = text.replace(/<b>([\s&nbsp;]+)<\/b>/gi, '\u00a0');
  782. text = text.replace(/<em>([\s&nbsp;]+)<\/em>/gi, '\u00a0');
  783. text = text.replace(/<i>([\s&nbsp;]+)<\/i>/gi, '\u00a0');
  784. text = text.replace(/<\/?(colgroup|col\s?([^>]+))>/gi, '');
  785. text = text.replace(/<(\/)?strong>/gi, '<$1b>');
  786. text = text.replace(/<(\/)?em>/gi, '<$1i>');
  787. wrapper.innerHTML = text;
  788. if (wrapper.firstChild.nodeType === GB.node.text) {
  789. text = wrapper.firstChild.data;
  790. text = text.replace(/^(&nbsp;+|\s+)/g, '');
  791. wrapper.firstChild.data = text;
  792. }
  793. elem = wrapper.firstChild;
  794. while (elem) {
  795. wrapper.parentNode.insertBefore(elem, wrapper);
  796. elem = wrapper.firstChild;
  797. }
  798. }
  799. pNode = wrapper.parentNode;
  800. if (pNode) {
  801. if (pNode.firstChild === wrapper && pNode.lastChild === wrapper) {
  802. pNode.parentNode.removeChild(pNode);
  803. } else {
  804. pNode.removeChild(wrapper);
  805. }
  806. }
  807. self.setImageEvent(true);
  808. }
  809. }, 50);
  810. return;
  811. }
  812. if (ev !== null) {
  813. clip = ev.clipboardData;
  814. this.stopEvent(ev);
  815. }
  816. text = this.trimSpace((this.undefined(clip) || clip === null) ?
  817. window.clipboardData.getData('Text') :
  818. clip.getData('text/plain'));
  819. if (text !== '') {
  820. text = text.replace(/\r/g, '');
  821. if (this.cheditor.mode === 'code') {
  822. div = this.doc.createElement('div');
  823. text = this.htmlEncode(text);
  824. text = text.replace(/\s{2,}/gm, '\n');
  825. text = text.replace(/[\u200b\ufeff\xa0\u3000]+/g, '');
  826. if (GB.browser.msie && GB.browser.version < 9) {
  827. text = text.replace(/\n/g, '<br />');
  828. text = text.replace(/\t/g, '__CHEDITOR_TAB_SPACE__');
  829. text = text.replace(/\s/gm, '&nbsp;');
  830. }
  831. div.innerHTML = text;
  832. div.id = 'clipboardData';
  833. this.insertHTML(div);
  834. return;
  835. }
  836. text = this.htmlEncode(text);
  837. text = text.replace(/[\r\n]+/g, '\n');
  838. text = text.split('\n').join('<br>');
  839. text = text.replace(/(\s{2,})/g, function (a, b) {
  840. space = b.split(/\s/);
  841. space.shift();
  842. return ' ' + space.join('&nbsp;');
  843. });
  844. this.insertHTML(text);
  845. self.setImageEvent(true);
  846. }
  847. },
  848. editAreaFocus: function () {
  849. this.editArea.focus();
  850. },
  851. resizeGetY: function (evt) {
  852. return GB.browser.msie ?
  853. window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop :
  854. evt.clientY + window.pageYOffset;
  855. },
  856. resizeStart: function (evt) {
  857. var self = this;
  858. self.currentRS.elNode = self.cheditor.mode === 'code' ? self.cheditor.textContent : self.cheditor.editArea;
  859. self.currentRS.cursorStartY = self.resizeGetY(evt);
  860. self.currentRS.elStartTop = parseInt(self.currentRS.elNode.style.height, 10);
  861. if (isNaN(self.currentRS.elStartTop)) {
  862. self.currentRS.elStartTop = 0;
  863. }
  864. evt = evt || window.event;
  865. self.resizeEditor.stopFunc = function (event) {
  866. self.resizeStop(event);
  867. };
  868. self.resizeEditor.moveFunc = function (event) {
  869. self.resizeMove(event);
  870. };
  871. if (GB.browser.msie) {
  872. self.setDesignMode(false);
  873. }
  874. self.currentRS.elNode.style.visibility = 'hidden';
  875. self.addEvent(document, 'mousemove', self.resizeEditor.moveFunc);
  876. self.addEvent(document, 'mouseup', self.resizeEditor.stopFunc);
  877. self.stopEvent(evt);
  878. },
  879. resizeMove: function (evt) {
  880. var offset = this.resizeGetY(evt),
  881. height = this.currentRS.elStartTop + offset - this.currentRS.cursorStartY;
  882. if (height < 1) {
  883. this.resizeStop(evt);
  884. height = 1;
  885. }
  886. this.config.editorHeight = this.currentRS.elNode.style.height = height + 'px';
  887. this.stopEvent(evt);
  888. },
  889. resizeStop: function (evt) {
  890. this.stopEvent(evt);
  891. this.removeEvent(document, 'mouseup', this.resizeEditor.stopFunc);
  892. this.removeEvent(document, 'mousemove', this.resizeEditor.moveFunc);
  893. this.currentRS.elNode.style.visibility = 'visible';
  894. if (GB.browser.msie) {
  895. this.setDesignMode(true);
  896. }
  897. if (this.cheditor.mode === 'code') {
  898. this.config.editorHeight = (parseInt(this.config.editorHeight, 10)
  899. + parseInt(this.cheditor.textContent.getAttribute('xbar-height'), 10)) + 'px';
  900. this.cheditor.textContent.focus();
  901. } else if (this.cheditor.mode === 'rich') {
  902. this.editAreaFocus();
  903. }
  904. },
  905. switchEditorMode: function (changeMode) {
  906. var self = this, i, className, interval;
  907. this.editAreaFocus();
  908. if (this.cheditor.mode === changeMode) {
  909. return;
  910. }
  911. for (i in this.cheditor.modetab) {
  912. if (this.cheditor.modetab.hasOwnProperty(i)) {
  913. className = this.cheditor.modetab[i].className;
  914. className = className.replace(/\-off$/, '');
  915. if (i !== changeMode) {
  916. this.cheditor.modetab[i].className = className + '-off';
  917. } else {
  918. this.cheditor.modetab[i].className = className;
  919. }
  920. }
  921. }
  922. switch (changeMode) {
  923. case 'rich':
  924. this.richMode();
  925. this.showTagSelector(true);
  926. break;
  927. case 'code':
  928. if (this.cheditor.modifyState) {
  929. interval = setInterval(function () {
  930. if (!self.cheditor.modifyState) {
  931. clearInterval(interval);
  932. self.editMode();
  933. }
  934. }, 10);
  935. } else {
  936. this.editMode();
  937. }
  938. this.showTagSelector(false);
  939. break;
  940. case 'preview':
  941. this.previewMode();
  942. this.showTagSelector(false);
  943. }
  944. this.cheditor.mode = changeMode;
  945. },
  946. initTemplate: function () {
  947. var self = this,
  948. httpRequest = null,
  949. showError = function (msg) {
  950. alert(self.templateFile + ' 파일 로딩 중 오류가 발생하였습니다.\n원인: ' + msg);
  951. },
  952. templateReady = function () {
  953. var event;
  954. if (httpRequest.readyState === 4) {
  955. if (httpRequest.status === 200) {
  956. try {
  957. self.xmlDoc = httpRequest.responseXML || httpRequest;
  958. self.loadTemplate(self.xmlDoc);
  959. if (self.W3CRange) {
  960. event = document.createEvent('Event');
  961. event.initEvent(self.cheditor.id, true, true);
  962. document.dispatchEvent(event);
  963. } else {
  964. document.documentElement.loadEvent = self.cheditor.id;
  965. }
  966. } catch (e) {
  967. showError(e.toString());
  968. }
  969. } else {
  970. showError('XMLHttpRequest. Status ' + httpRequest.status);
  971. }
  972. }
  973. };
  974. if (window.XMLHttpRequest) {
  975. httpRequest = new XMLHttpRequest();
  976. if (httpRequest.overrideMimeType) {
  977. httpRequest.overrideMimeType('text/xml');
  978. }
  979. httpRequest.onreadystatechange = templateReady;
  980. try {
  981. httpRequest.open('GET', self.templatePath, true);
  982. }
  983. catch (e) {
  984. showError(e + '참고: 에디터를 웹 서버에서 실행하여 주십시오.');
  985. }
  986. httpRequest.send();
  987. } else if (window.ActiveXObject) {
  988. httpRequest = new window.ActiveXObject('Microsoft.XMLDOM');
  989. httpRequest.async = true;
  990. httpRequest.onreadystatechange = templateReady;
  991. httpRequest.load(self.templatePath);
  992. } else {
  993. showError('현재 브라우저에서 ' + self.templateFile + ' 파일을 사용할 수 없습니다.');
  994. }
  995. },
  996. getCDATASection: function (node) {
  997. var text = node.textContent || node.text;
  998. return this.trimSpace(text.replace(/\n/g, '').replace(/(\s+?)<([^>]*)>/g, '<$2>'));
  999. },
  1000. setToolbarBgPosition: function (elem, attr) {
  1001. elem.style.backgroundPosition = attr;
  1002. },
  1003. getToolbarBgPosition: function (elem) {
  1004. var pos;
  1005. switch (elem.className) {
  1006. case 'cheditor-tb-bg': pos = 3; break;
  1007. case 'cheditor-tb-bg-last': pos = 6; break;
  1008. case 'cheditor-tb-bg-single': pos = 9; break;
  1009. case 'cheditor-tb-bg30-first': pos = 12; break;
  1010. case 'cheditor-tb-bg30': pos = 15; break;
  1011. case 'cheditor-tb-bg30-last': pos = 18; break;
  1012. case 'cheditor-tb-bg55': pos = 21; break;
  1013. case 'cheditor-tb-bg40': pos = 24; break;
  1014. case 'cheditor-tb-bg44': pos = 27; break;
  1015. case 'cheditor-tb-bgcombo': pos = 30; break;
  1016. case 'cheditor-tb-bgcombo-last': pos = 33; break;
  1017. default: pos = 0;
  1018. }
  1019. return pos;
  1020. },
  1021. toolbarMouseOverUp: function (elem) {
  1022. var pos, obj;
  1023. if (elem.checked) {
  1024. return;
  1025. }
  1026. this.setToolbarBgPosition(elem.button, '0 ' + (~(((elem.pos + 1) * elem.height)) + 1) + 'px');
  1027. if ((elem.name === 'combobox' && elem.prev && elem.prev.checked) ||
  1028. (elem.name === 'combo' && elem.next && elem.next.checked)) {
  1029. return;
  1030. }
  1031. if (elem.type === 'combobox') {
  1032. if (elem.prev.checked) {
  1033. return;
  1034. }
  1035. obj = elem.prev;
  1036. pos = '0px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px';
  1037. this.setToolbarBgPosition(obj.button, pos);
  1038. } else if (elem.type === 'combo') {
  1039. if (elem.prev && !elem.prev.checked && !elem.prev.active) {
  1040. obj = elem.prev;
  1041. pos = (~(obj.width) + 1) + 'px ' + (~(obj.pos * obj.height) + 1) + 'px';
  1042. this.setToolbarBgPosition(obj.button, pos);
  1043. }
  1044. if (elem.next) {
  1045. if (elem.next.checked) {
  1046. return;
  1047. }
  1048. obj = elem.next;
  1049. pos = (~(obj.width) + 1) + 'px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px';
  1050. this.setToolbarBgPosition(obj.button, pos);
  1051. }
  1052. } else {
  1053. if (!elem.prev || (elem.prev && elem.prev.checked)) {
  1054. return;
  1055. }
  1056. obj = elem.prev;
  1057. if (obj.className === 'cheditor-tb-bg-first') {
  1058. pos = (~(obj.width) + 1) + 'px 0';
  1059. } else {
  1060. pos = (~(obj.width) + 1) + 'px ' + (~(obj.pos * obj.height) + 1) + 'px';
  1061. }
  1062. this.setToolbarBgPosition(obj.button, pos);
  1063. }
  1064. },
  1065. toolbarMouseDownOut: function (elem, mousedown) {
  1066. if (elem.next && elem.next.checked && !mousedown) {
  1067. this.setToolbarBgPosition(elem.button, (~(elem.width * 2) + 1) + 'px ' +
  1068. (~(elem.pos * elem.height) + 1) + 'px');
  1069. }
  1070. if (elem.prev) {
  1071. if (elem.prev.active || (elem.prev.type === 'combo' && elem.checked)) {
  1072. return;
  1073. }
  1074. if (elem.prev.checked) {
  1075. this.setToolbarBgPosition(elem.prev.button, '0 ' +
  1076. (~((elem.prev.pos + 2) * elem.prev.height) + 1) + 'px');
  1077. return;
  1078. }
  1079. if (mousedown) {
  1080. this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' +
  1081. (~(elem.prev.pos * elem.prev.height) + 1) + 'px');
  1082. } else {
  1083. this.setToolbarBgPosition(elem.prev.button,
  1084. '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px');
  1085. }
  1086. }
  1087. },
  1088. toolbarButtonChecked: function (elem) {
  1089. this.setToolbarBgPosition(elem.button, '0 ' + (~((elem.pos + 2) * elem.height) + 1) + 'px');
  1090. if (elem.prev && elem.prev.type === 'combo') {
  1091. if (elem.prev.checked || elem.checked) {
  1092. return;
  1093. }
  1094. this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' +
  1095. (~(elem.prev.pos * elem.prev.height) + 1) + 'px');
  1096. }
  1097. if (elem.prev && !elem.prev.checked) {
  1098. if (elem.checked) {
  1099. this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' +
  1100. (~(elem.prev.pos * elem.prev.height) + 1) + 'px');
  1101. } else {
  1102. this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px');
  1103. }
  1104. }
  1105. },
  1106. toolbarButtonUnchecked: function (elem) {
  1107. if (elem.type === 'combobox' && !elem.checked) {
  1108. if (elem.prev.checked) {
  1109. this.setToolbarBgPosition(elem.button,
  1110. (~(elem.width) + 1) + 'px ' + (~(((elem.pos + 1) * elem.height)) + 1) + 'px');
  1111. return;
  1112. }
  1113. this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px');
  1114. }
  1115. this.setToolbarBgPosition(elem.button, '0 ' + (~(elem.pos * elem.height) + 1) + 'px');
  1116. if (elem.prev && elem.prev.name === 'BackColor') {
  1117. this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px');
  1118. }
  1119. },
  1120. makeToolbarGrayscale: function (image) {
  1121. var context, imageData, filter, imgWidth = image.width, imgHeight = image.height,
  1122. canvas = this.doc.createElement('canvas');
  1123. filter = function (pixels) {
  1124. var d = pixels.data, i, r, g, b;
  1125. for (i = 0; i < d.length; i += 4) {
  1126. r = d[i];
  1127. g = d[i + 1];
  1128. b = d[i + 2];
  1129. d[i] = d[i + 1] = d[i + 2] = (r + g + b) / 3;
  1130. }
  1131. return pixels;
  1132. };
  1133. context = canvas.getContext('2d');
  1134. canvas.width = imgWidth;
  1135. canvas.height = imgHeight;
  1136. context.drawImage(image, 0, 0);
  1137. imageData = context.getImageData(0, 0, imgWidth, imgHeight);
  1138. filter(imageData);
  1139. context.putImageData(imageData, 0, 0);
  1140. return canvas.toDataURL();
  1141. },
  1142. toolbarSetBackgroundImage: function (elem, disable) {
  1143. var css = elem.firstChild.className,
  1144. tbEnable = (this.cheditor.toolbarGrayscale && elem.firstChild.style.backgroundImage);
  1145. css = css.replace(/-disable$/i, '');
  1146. if (disable) {
  1147. if (tbEnable) {
  1148. elem.firstChild.style.backgroundImage = 'url(' + this.cheditor.toolbarGrayscale + ')';
  1149. }
  1150. css = css + '-disable';
  1151. elem.style.cursor = 'default';
  1152. } else {
  1153. if (tbEnable) {
  1154. elem.firstChild.style.backgroundImage = 'url(' + this.toolbar.icon + ')';
  1155. }
  1156. elem.style.cursor = 'pointer';
  1157. }
  1158. elem.firstChild.className = css;
  1159. },
  1160. toolbarDisable: function (elem, disable) {
  1161. if (disable) {
  1162. this.toolbarSetBackgroundImage(elem.button, true);
  1163. this.toolbarButtonUnchecked(elem);
  1164. this.toolbarMouseDownOut(elem);
  1165. this.toolbar[elem.name].disabled = true;
  1166. return true;
  1167. }
  1168. this.toolbarSetBackgroundImage(elem.button, false);
  1169. this.toolbar[elem.name].disabled = false;
  1170. return false;
  1171. },
  1172. colorConvert: function (color, which, opacity) {
  1173. var colorDefs = [
  1174. {
  1175. re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
  1176. process: function (bits) {
  1177. return [
  1178. parseInt(bits[1], 10),
  1179. parseInt(bits[2], 10),
  1180. parseInt(bits[3], 10),
  1181. 1
  1182. ];
  1183. }
  1184. },
  1185. {
  1186. re: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d+(?:\.\d+)?|\.\d+)\s*\)/,
  1187. process: function (bits) {
  1188. return [
  1189. parseInt(bits[1], 10),
  1190. parseInt(bits[2], 10),
  1191. parseInt(bits[3], 10),
  1192. parseFloat(bits[4])
  1193. ];
  1194. }
  1195. },
  1196. {
  1197. re: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
  1198. process: function (bits) {
  1199. return [
  1200. parseInt(bits[1], 16),
  1201. parseInt(bits[2], 16),
  1202. parseInt(bits[3], 16),
  1203. 1
  1204. ];
  1205. }
  1206. },
  1207. {
  1208. re: /^([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/,
  1209. process: function (bits) {
  1210. return [
  1211. parseInt(bits[1] * 2, 16),
  1212. parseInt(bits[2] * 2, 16),
  1213. parseInt(bits[3] * 2, 16),
  1214. 1
  1215. ];
  1216. }
  1217. }
  1218. ], r = null, g = null, b = null, a = null, i, re, processor, bits, channels, min, rData = null;
  1219. if (!which) {
  1220. which = 'rgba';
  1221. }
  1222. color = color.replace(/^\s*#|\s*$/g, '');
  1223. if (color.length === 3) {
  1224. color = color.replace(/(.)/g, '$1$1');
  1225. }
  1226. color = color.toLowerCase();
  1227. which = which.toLowerCase();
  1228. for (i = 0; i < colorDefs.length; i++) {
  1229. re = colorDefs[i].re;
  1230. processor = colorDefs[i].process;
  1231. bits = re.exec(color);
  1232. if (bits) {
  1233. channels = processor(bits);
  1234. r = channels[0];
  1235. g = channels[1];
  1236. b = channels[2];
  1237. a = channels[3];
  1238. }
  1239. }
  1240. r = (r < 0 || isNaN(r)) ? 0 : ((r > 255) ? 255 : r);
  1241. g = (g < 0 || isNaN(g)) ? 0 : ((g > 255) ? 255 : g);
  1242. b = (b < 0 || isNaN(b)) ? 0 : ((b > 255) ? 255 : b);
  1243. a = (a < 0 || isNaN(a)) ? 0 : ((a > 1) ? 1 : a);
  1244. function hex(x) {
  1245. return ('0' + parseInt(x, 10).toString(16)).slice(-2);
  1246. }
  1247. switch (which) {
  1248. case 'rgba':
  1249. if (opacity) {
  1250. a = (255 - (min = Math.min(r, g, b))) / 255;
  1251. r = ((r - min) / a).toFixed(0);
  1252. g = ((g - min) / a).toFixed(0);
  1253. b = ((b - min) / a).toFixed(0);
  1254. a = a.toFixed(4);
  1255. }
  1256. rData = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
  1257. break;
  1258. case 'rgb':
  1259. rData = 'rgb(' + r + ',' + g + ',' + b + ')';
  1260. break;
  1261. case 'hex':
  1262. if (isNaN(parseInt(r, 10)) || isNaN(parseInt(g, 10)) || isNaN(parseInt(b, 10))) {
  1263. return color;
  1264. }
  1265. rData = '#' + hex(r) + hex(g) + hex(b);
  1266. break;
  1267. }
  1268. return rData;
  1269. },
  1270. toolbarUpdate: function (srcElement) {
  1271. var toolbar = this.toolbar,
  1272. range = this.getRange(),
  1273. isCollapsed = this.rangeCollapsed(range),
  1274. sType = GB.selection.text,
  1275. bControl = false, bTable = false, ancestorsLen = 0, bNoOff = { 'Link': 1 }, ancestors = [],
  1276. i, j, btn, cmd, autoOff, bDisable, el, wrapper, fontAttr, oldName, span, newAttr, defaultAttr,
  1277. state, css, node, alignment, pNode;
  1278. pNode = srcElement || this.getRangeElement(range);
  1279. switch (pNode.nodeType) {
  1280. case GB.node.element:
  1281. sType = GB.selection.element;
  1282. break;
  1283. case GB.node.text:
  1284. sType = GB.selection.text;
  1285. pNode = pNode.parentNode;
  1286. break;
  1287. default:
  1288. return;
  1289. }
  1290. if (sType === GB.selection.element && !isCollapsed) {
  1291. bControl = GB.offElementTags[pNode.nodeName.toLowerCase()];
  1292. } else {
  1293. node = pNode;
  1294. while (node && node.nodeType === GB.node.element && node.nodeName.toLowerCase() !== 'body') {
  1295. ancestors.push(node);
  1296. if (node.nodeName.toLowerCase() === 'td' || node.nodeName.toLowerCase() === 'th') {
  1297. bTable = true;
  1298. }
  1299. node = node.parentNode;
  1300. }
  1301. ancestorsLen = ancestors.length;
  1302. }
  1303. if (!bTable && sType === GB.selection.element &&
  1304. (pNode.nodeName.toLowerCase() === 'table' || pNode.nodeName.toLowerCase() === 'td' ||
  1305. pNode.nodeName.toLowerCase() === 'th')) {
  1306. bTable = true;
  1307. }
  1308. alignment = { JustifyCenter: 'center', JustifyRight: 'right', JustifyFull: 'justify' };
  1309. for (i in toolbar) {
  1310. if (!toolbar.hasOwnProperty(i)) {
  1311. continue;
  1312. }
  1313. btn = toolbar[i];
  1314. if (!btn.cmd) {
  1315. continue;
  1316. }
  1317. cmd = btn.cmd;
  1318. autoOff = false;
  1319. if (bControl && sType === GB.selection.element) {
  1320. if (btn.group !== 'Alignment') {
  1321. autoOff = !(pNode.nodeName.toLowerCase() === 'img' && bNoOff[cmd]);
  1322. }
  1323. }
  1324. if (btn.name === 'ModifyTable') {
  1325. autoOff = !bTable;
  1326. }
  1327. bDisable = this.toolbarDisable(btn, autoOff);
  1328. if (btn.name === 'ForeColor' || btn.name === 'BackColor') {
  1329. btn.button.lastChild.style.display = bDisable ? 'none' : 'block';
  1330. }
  1331. if (btn.autocheck === null) {
  1332. continue;
  1333. }
  1334. switch (cmd) {
  1335. case 'Copy':
  1336. case 'Cut':
  1337. this.toolbarDisable(btn, isCollapsed);
  1338. break;
  1339. case 'UnLink':
  1340. if (GB.browser.firefox) {
  1341. this.toolbarDisable(btn, (pNode.nodeName.toLowerCase() !== 'a' && !pNode.getAttribute('href')));
  1342. } else {
  1343. this.toolbarDisable(btn, this.doc.queryCommandEnabled(cmd) === false);
  1344. }
  1345. break;
  1346. case 'FormatBlock':
  1347. wrapper = btn.button.firstChild;
  1348. oldName = wrapper.firstChild;
  1349. el = false;
  1350. span = document.createElement('span');
  1351. for (j = 0; j < ancestorsLen; j++) {
  1352. if (GB.formatBlock[ancestors[j].nodeName]) {
  1353. span.appendChild(document.createTextNode(ancestors[j].nodeName));
  1354. wrapper.replaceChild(span, oldName);
  1355. el = true;
  1356. break;
  1357. }
  1358. }
  1359. if (!el) {
  1360. span.appendChild(document.createTextNode('스타일'));
  1361. wrapper.replaceChild(span, oldName);
  1362. }
  1363. this.unselectionElement(span);
  1364. break;
  1365. case 'ForeColor':
  1366. case 'BackColor':
  1367. if (cmd === 'BackColor' && !GB.browser.msie) {
  1368. cmd = 'HiliteColor';
  1369. }
  1370. fontAttr = this.doc.queryCommandValue(cmd);
  1371. if (fontAttr && !/^[rgb|#]/.test(fontAttr)) {
  1372. fontAttr = (((fontAttr & 0x0000ff) << 16) | (fontAttr & 0x00ff00) | ((fontAttr & 0xff0000) >>> 16)).toString(16);
  1373. fontAttr = '#000000'.slice(0, 7 - fontAttr.length) + fontAttr;
  1374. } else {
  1375. fontAttr = (cmd === 'ForeColor') ? this.config.editorFontColor : this.config.editorBgColor;
  1376. }
  1377. btn.button.lastChild.style.backgroundColor = fontAttr;
  1378. break;
  1379. case 'FontName':
  1380. case 'FontSize':
  1381. fontAttr = this.doc.queryCommandValue(cmd);
  1382. wrapper = btn.button.firstChild;
  1383. span = this.doc.createElement('span');
  1384. if (cmd === 'FontSize') {
  1385. fontAttr = pNode.style.fontSize;
  1386. if (!fontAttr) {
  1387. for (i = 0; i < ancestors.length; i++) {
  1388. fontAttr = ancestors[i].style.fontSize;
  1389. if (fontAttr) {
  1390. break;
  1391. }
  1392. }
  1393. }
  1394. }
  1395. if (fontAttr) {
  1396. newAttr = fontAttr;
  1397. newAttr = newAttr.replace(/'/g, '');
  1398. span.appendChild(this.doc.createTextNode(newAttr));
  1399. wrapper.replaceChild(span, wrapper.firstChild);
  1400. }
  1401. if (!span.hasChildNodes()) {
  1402. defaultAttr = (cmd === 'FontSize') ? this.config.editorFontSize : this.config.editorFontName;
  1403. if (wrapper.hasChildNodes()) {
  1404. wrapper.removeChild(wrapper.firstChild);
  1405. }
  1406. defaultAttr = defaultAttr.replace(/'/g, '');
  1407. span.appendChild(this.doc.createTextNode(defaultAttr));
  1408. wrapper.appendChild(span);
  1409. }
  1410. this.unselectionElement(span);
  1411. break;
  1412. case 'LineHeight':
  1413. wrapper = btn.button.firstChild;
  1414. this.unselectionElement(wrapper.firstChild);
  1415. break;
  1416. default:
  1417. if (!this.doc.queryCommandSupported(cmd)) {
  1418. continue;
  1419. }
  1420. state = this.doc.queryCommandState(cmd);
  1421. if (state === null) {
  1422. continue;
  1423. }
  1424. if (GB.browser.msie && state === false && alignment[cmd]) {
  1425. el = pNode;
  1426. while (el && el.nodeName.toLowerCase() !== 'body') {
  1427. if (GB.lineHeightBlockTags[el.nodeName.toLowerCase()]) {
  1428. css = this.getCssValue(el);
  1429. if (css) {
  1430. for (j = 0; j < css.length; j++) {
  1431. if (css[j].name.toLowerCase() === 'text-align' && css[j].value === alignment[cmd]) {
  1432. state = true;
  1433. break;
  1434. }
  1435. }
  1436. }
  1437. }
  1438. el = el.parentNode;
  1439. }
  1440. }
  1441. if (state) {
  1442. btn.checked = true;
  1443. this.toolbarButtonChecked(btn);
  1444. if (btn.type === 'combo' && btn.name === btn.next.node) {
  1445. btn.next.active = true;
  1446. this.setToolbarBgPosition(btn.next.button,
  1447. (~(btn.next.width) + 1) + 'px ' + (~(((btn.next.pos + 1) * btn.next.height)) + 1) + 'px');
  1448. }
  1449. } else {
  1450. this.toolbarButtonUnchecked(btn);
  1451. btn.checked = false;
  1452. if (btn.next) {
  1453. btn.next.active = false;
  1454. if (btn.type === 'combo' && btn.name === btn.next.node) {
  1455. this.toolbarButtonUnchecked(btn.next);
  1456. }
  1457. }
  1458. }
  1459. }
  1460. }
  1461. },
  1462. createButton: function (name, attr, prev) {
  1463. var self = this,
  1464. elem, icon, btnIcon, iconPos, method, cmd, check, type, node, btnHeight, btnWidth, text,
  1465. span, obj, btnClass, comboOut;
  1466. method = attr.getElementsByTagName('Execution')[0].getAttribute('method');
  1467. cmd = attr.getElementsByTagName('Execution')[0].getAttribute('value');
  1468. check = attr.getAttribute('check');
  1469. type = attr.getAttribute('type');
  1470. node = attr.getAttribute('node');
  1471. btnClass = attr.getAttribute('class');
  1472. btnWidth = attr.getAttribute('width');
  1473. btnHeight = attr.getAttribute('height');
  1474. elem = document.createElement('div');
  1475. elem.style.width = btnWidth + 'px';
  1476. elem.setAttribute('name', name);
  1477. elem.style.height = btnHeight + 'px';
  1478. elem.style.border = '0px solid transparent';
  1479. icon = attr.getElementsByTagName('Icon')[0];
  1480. btnIcon = document.createElement('div');
  1481. btnIcon.className = icon.getAttribute('class');
  1482. btnIcon.style.marginLeft = icon.getAttribute('margin') || '3px';
  1483. iconPos = icon.getAttribute('position');
  1484. if (iconPos) {
  1485. btnIcon.style.backgroundImage = 'url(' + self.toolbar.icon + ')';
  1486. btnIcon.style.backgroundRepeat = 'no-repeat';
  1487. self.setToolbarBgPosition(btnIcon, (~iconPos + 1) + 'px center');
  1488. } else {
  1489. text = icon.getAttribute('alt');
  1490. if (text) {
  1491. span = document.createElement('span');
  1492. span.appendChild(document.createTextNode(text));
  1493. btnIcon.appendChild(span);
  1494. }
  1495. }
  1496. elem.appendChild(btnIcon);
  1497. obj = {
  1498. 'autocheck': check,
  1499. 'button': elem,
  1500. 'className': btnClass,
  1501. 'checked': false,
  1502. 'cmd': cmd,
  1503. 'colorNode': {},
  1504. 'disabled': false,
  1505. 'group': '',
  1506. 'height': btnHeight,
  1507. 'method': method,
  1508. 'name': name,
  1509. 'next': null,
  1510. 'node': node,
  1511. 'num': 0,
  1512. 'pos': 0,
  1513. 'prev': prev,
  1514. 'type': type,
  1515. 'width': btnWidth
  1516. };
  1517. if (prev) {
  1518. prev.next = obj;
  1519. }
  1520. elem.attr = obj;
  1521. self.toolbar[name] = obj;
  1522. self.addEvent(elem, 'mouseover', function (ev) {
  1523. if (!obj.disabled) {
  1524. self.toolbarMouseOverUp(obj);
  1525. }
  1526. self.stopEvent(ev || window.event);
  1527. });
  1528. self.addEvent(elem, 'mousedown', function (ev) {
  1529. if (!obj.checked && !obj.disabled) {
  1530. self.toolbarButtonChecked(obj);
  1531. self.toolbarMouseDownOut(obj, true);
  1532. if (obj.prev && obj.prev.type === 'combo' && !obj.prev.checked) {
  1533. self.setToolbarBgPosition(obj.prev.button,
  1534. '0 ' + (~((self.getToolbarBgPosition(obj.prev.button) + 1) * obj.prev.height) + 1) + 'px');
  1535. }
  1536. }
  1537. if (obj.next) {
  1538. obj.next.button.style.visibility = 'hidden';
  1539. obj.next.button.style.visibility = 'visible';
  1540. }
  1541. self.stopEvent(ev || window.event);
  1542. });
  1543. self.addEvent(elem, 'click', function (ev) {
  1544. if (obj.disabled) {
  1545. return;
  1546. }
  1547. switch (obj.method) {
  1548. case 'doCmd':
  1549. self.backupRange();
  1550. self.doCmd(obj.cmd, null);
  1551. break;
  1552. case 'windowOpen':
  1553. self.windowOpen(obj.cmd);
  1554. break;
  1555. case 'showPulldown':
  1556. if (obj.checked) {
  1557. obj.checked = false;
  1558. self.boxHideAll();
  1559. self.toolbarButtonUnchecked(obj);
  1560. return;
  1561. }
  1562. obj.checked = true;
  1563. self.showPulldown(obj.cmd, obj.button);
  1564. self.toolbarButtonChecked(obj);
  1565. self.toolbarMouseDownOut(obj, true);
  1566. break;
  1567. default:
  1568. alert('지원하지 않는 명령입니다.');
  1569. }
  1570. self.stopEvent(ev || window.event);
  1571. });
  1572. comboOut = function (combo, startPos) {
  1573. self.setToolbarBgPosition(combo.button,
  1574. startPos + 'px ' + (~(((self.getToolbarBgPosition(combo.button) + (combo.checked ? 2 : 1)) * combo.height)) + 1) + 'px');
  1575. };
  1576. self.addEvent(elem, 'mouseout', function () {
  1577. if (!obj.checked) {
  1578. if (obj.type === 'combo') {
  1579. if (obj.next) {
  1580. if (!obj.next.checked) {
  1581. self.toolbarButtonUnchecked(obj.next);
  1582. self.toolbarMouseDownOut(obj.next, false);
  1583. } else {
  1584. return;
  1585. }
  1586. }
  1587. }
  1588. if (obj.type === 'combobox' && obj.prev.checked) {
  1589. self.setToolbarBgPosition(obj.button,
  1590. (~(obj.width) + 1) + 'px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px');
  1591. return;
  1592. }
  1593. self.toolbarButtonUnchecked(obj);
  1594. self.toolbarMouseDownOut(obj, false);
  1595. } else {
  1596. if (obj.node && obj.node === obj.prev.name) {
  1597. if (!obj.prev.checked) {
  1598. self.setToolbarBgPosition(obj.prev.button,
  1599. '0 ' + (~((self.getToolbarBgPosition(obj.prev.button) + 1) * obj.prev.height) + 1) + 'px');
  1600. }
  1601. comboOut(obj, 0);
  1602. }
  1603. }
  1604. });
  1605. return obj;
  1606. },
  1607. showToolbar: function (toolbar, toolbarWrapper) {
  1608. var self = this,
  1609. i, j, grpName, btn, btnLen, prevObj, attr, btnName, btnObj = null, btnNum, spacer,
  1610. currentColor, fullscreen, child, len,
  1611. toolbarIcon = toolbar.getElementsByTagName('Image').item(0).getAttribute('file'),
  1612. tmpArr = toolbarIcon.split(/\./),
  1613. group = toolbar.getElementsByTagName('Group'),
  1614. grpNum = group.length,
  1615. appendSpaceBlock = function (pNode) {
  1616. var split = document.createElement('div');
  1617. split.className = 'cheditor-tb-split';
  1618. pNode.appendChild(split);
  1619. },
  1620. onClickEventHandler = function () {
  1621. if (self.setFullScreenMode) {
  1622. this.className = 'cheditor-tb-fullscreen';
  1623. this.setAttribute('title', '전체 화면');
  1624. } else {
  1625. this.className = 'cheditor-tb-fullscreen-actual';
  1626. this.setAttribute('title', '이전 크기로 복원');
  1627. }
  1628. self.fullScreenMode();
  1629. };
  1630. self.toolbar.icon = self.config.iconPath + toolbarIcon;
  1631. self.toolbar.iconDisable = self.config.iconPath + tmpArr[0] + '-disable' + '.' + tmpArr[1];
  1632. toolbarWrapper.className = 'cheditor-tb-wrapper';
  1633. fullscreen = document.createElement('span');
  1634. if (self.config.useFullScreen === true) {
  1635. fullscreen.appendChild(document.createTextNode('\u00a0'));
  1636. fullscreen.className = 'cheditor-tb-fullscreen';
  1637. fullscreen.setAttribute('title', '전체 화면');
  1638. (function () {
  1639. fullscreen.onclick = onClickEventHandler;
  1640. })();
  1641. } else {
  1642. fullscreen.clsaaName = 'cheditor-tb-fullscreen-disable';
  1643. }
  1644. toolbarWrapper.appendChild(fullscreen);
  1645. for (i = 0; i < grpNum; i++) {
  1646. grpName = group[i].getAttribute('name');
  1647. if (grpName === 'Split') {
  1648. appendSpaceBlock(toolbarWrapper);
  1649. continue;
  1650. }
  1651. btn = group[i].getElementsByTagName('Button');
  1652. btnLen = btn.length;
  1653. btnNum = 0; btnObj = null;
  1654. for (j = 0; j < btnLen; j++) {
  1655. attr = btn[j].getElementsByTagName('Attribute')[0];
  1656. btnName = btn[j].getAttribute('name');
  1657. if (!attr.getAttribute('node') && self.config['use' + btnName] !== true) {
  1658. continue;
  1659. }
  1660. if (attr.getAttribute('type') === 'combobox' && self.config['use' + attr.getAttribute('node')] !== true) {
  1661. continue;
  1662. }
  1663. btnObj = self.createButton(btnName, attr, btnObj);
  1664. self.toolbar[btnObj.name].num = btnNum++;
  1665. self.toolbar[btnObj.name].group = grpName;
  1666. if (btn[j].getAttribute('tooltip') !== null) {
  1667. btnObj.button.setAttribute('title', btn[j].getAttribute('tooltip'));
  1668. }
  1669. if (btnObj.name === 'ForeColor' || btnObj.name === 'BackColor') {
  1670. currentColor = document.createElement('div');
  1671. currentColor.className = 'cheditor-tb-color-btn';
  1672. currentColor.style.backgroundColor = attr.getAttribute('default');
  1673. btnObj.button.appendChild(currentColor);
  1674. }
  1675. toolbarWrapper.appendChild(btnObj.button);
  1676. }
  1677. if (btnObj === null) {
  1678. continue;
  1679. }
  1680. prevObj = btnObj.prev;
  1681. if (!prevObj) {
  1682. btnObj.button.className = btnObj.className;
  1683. if (btnObj.className === 'cheditor-tb-bg') {
  1684. btnObj.className = btnObj.className + '-single';
  1685. btnObj.button.className = btnObj.className;
  1686. }
  1687. btnObj.pos = self.getToolbarBgPosition(btnObj.button);
  1688. } else {
  1689. btnObj.className = btnObj.className + '-last';
  1690. btnObj.button.className = btnObj.className;
  1691. btnObj.pos = self.getToolbarBgPosition(btnObj.button);
  1692. while (prevObj) {
  1693. prevObj.button.className = prevObj.className;
  1694. prevObj.pos = self.getToolbarBgPosition(prevObj.button);
  1695. btnObj = prevObj;
  1696. prevObj = prevObj.prev;
  1697. }
  1698. btnObj.className = btnObj.className + '-first';
  1699. btnObj.button.className = btnObj.className;
  1700. btnObj.pos = self.getToolbarBgPosition(btnObj.button);
  1701. }
  1702. spacer = document.createElement('div');
  1703. spacer.className = 'cheditor-tb-button-spacer';
  1704. toolbarWrapper.appendChild(spacer);
  1705. }
  1706. appendSpaceBlock(toolbarWrapper);
  1707. if (GB.browser.msie) {
  1708. child = toolbarWrapper.getElementsByTagName('div');
  1709. len = child.length;
  1710. for (i = 0; i < len; i++) {
  1711. self.unselectionElement(child[i]);
  1712. }
  1713. self.unselectionElement(toolbarWrapper);
  1714. } else {
  1715. self.unselectionElement(toolbarWrapper);
  1716. }
  1717. },
  1718. unselectionElement: function (elem) {
  1719. if (!elem || elem.nodeType !== GB.node.element) {
  1720. return;
  1721. }
  1722. if (GB.browser.msie) {
  1723. elem.setAttribute('unselectable', 'on');
  1724. elem.setAttribute('contentEditable', 'false');
  1725. } else {
  1726. elem.onselectstart = new Function('return false');
  1727. }
  1728. },
  1729. createEditorElement: function (container, toolbar) {
  1730. var child = container.firstChild,
  1731. self = this,
  1732. i, id, tab, tabId, editArea, done = false, frameEl = false, tryScroll, textContent, node,
  1733. onClickEventHandler = function () {
  1734. self.switchEditorMode(this.getAttribute('mode'));
  1735. },
  1736. onMouseDownEventHandler = function (evt) {
  1737. self.resizeStart(evt);
  1738. },
  1739. modeOnMouseDownEventHandler = function (evt) {
  1740. self.backupRange();
  1741. self.stopEvent(evt);
  1742. },
  1743. pNode = self.cheditor.textarea.parentNode,
  1744. nNode = self.cheditor.textarea.nextSibling;
  1745. if (!child) {
  1746. return;
  1747. }
  1748. do {
  1749. id = child.getAttribute('id');
  1750. switch (id) {
  1751. case 'toolbar':
  1752. self.showToolbar(toolbar, child);
  1753. self.cheditor.toolbarWrapper = child;
  1754. break;
  1755. case 'viewMode':
  1756. self.cheditor[id] = child;
  1757. self.cheditor.mode = 'rich';
  1758. if (child.hasChildNodes()) {
  1759. tab = child.childNodes;
  1760. self.cheditor.modetab = {};
  1761. for (i = 0; i < tab.length; i++) {
  1762. tabId = tab[i].getAttribute('id');
  1763. if (!tabId) {
  1764. continue;
  1765. }
  1766. if ((tabId === 'code' && self.config.useSource === false) ||
  1767. (tabId === 'preview' && self.config.usePreview === false)) {
  1768. tab[i].style.display = 'none';
  1769. tab[i].removeAttribute('id');
  1770. continue;
  1771. }
  1772. tab[i].setAttribute('mode', tabId);
  1773. tab[i].onclick = onClickEventHandler;
  1774. tab[i].onmousedown = modeOnMouseDownEventHandler;
  1775. tab[i].removeAttribute('id');
  1776. self.cheditor.modetab[tabId] = tab[i];
  1777. self.unselectionElement(tab[i]);
  1778. }
  1779. }
  1780. break;
  1781. case 'editWrapper':
  1782. node = child.firstChild;
  1783. while (node) {
  1784. if (node.nodeName.toLowerCase() === 'iframe') {
  1785. editArea = node;
  1786. } else if (node.nodeName.toLowerCase() === 'textarea') {
  1787. textContent = node;
  1788. }
  1789. node = node.nextSibling;
  1790. }
  1791. editArea.style.height = self.config.editorHeight;
  1792. editArea.style.backgroundColor = this.config.editorBgColor;
  1793. self.cheditor.editArea = editArea;
  1794. self.cheditor.editWrapper = child;
  1795. self.cheditor.textContent = textContent;
  1796. break;
  1797. case 'modifyBlock':
  1798. self.cheditor.editBlock = child;
  1799. break;
  1800. case 'tagPath':
  1801. if (self.config.showTagPath) {
  1802. self.cheditor.tagPath = child.firstChild;
  1803. child.style.display = 'block';
  1804. }
  1805. break;
  1806. case 'resizeBar':
  1807. self.cheditor.resizeBar = child;
  1808. child.onmousedown = onMouseDownEventHandler;
  1809. self.unselectionElement(child);
  1810. break;
  1811. default: break;
  1812. }
  1813. child.removeAttribute('id');
  1814. child = child.nextSibling;
  1815. } while (child);
  1816. if (!nNode) {
  1817. pNode.appendChild(container);
  1818. } else {
  1819. pNode.insertBefore(container, nNode);
  1820. }
  1821. function ready() {
  1822. if (done) {
  1823. return;
  1824. }
  1825. done = true;
  1826. }
  1827. if (GB.browser.msie) {
  1828. frameEl = window.frameElement !== null;
  1829. if (document.documentElement.doScroll && !frameEl) {
  1830. tryScroll = function () {
  1831. if (done) {
  1832. return;
  1833. }
  1834. try {
  1835. document.documentElement.doScroll('left');
  1836. ready();
  1837. } catch (e) {
  1838. setTimeout(tryScroll, 10);
  1839. }
  1840. };
  1841. tryScroll();
  1842. }
  1843. self.addEvent(document, 'readystatechange', function () {
  1844. if (document.readyState === 'complete') {
  1845. ready();
  1846. }
  1847. });
  1848. } else {
  1849. self.addEvent(document, 'DOMContentLoaded', function () {
  1850. ready();
  1851. });
  1852. }
  1853. container.style.width = self.config.editorWidth;
  1854. self.cheditor.container = container;
  1855. },
  1856. loadTemplate: function (xmlDoc) {
  1857. var self = this,
  1858. tmpl = xmlDoc.getElementsByTagName('Template').item(0),
  1859. toolbar = tmpl.getElementsByTagName('Toolbar').item(0),
  1860. cdata = tmpl.getElementsByTagName('Container').item(0).getElementsByTagName('Html').item(0),
  1861. html = self.getCDATASection(cdata),
  1862. tmpDiv = document.createElement('div'),
  1863. container, popupWindow, modalFrame, dragHandle;
  1864. if (!(tmpl.getElementsByTagName('Image').item(0).getAttribute('file'))) {
  1865. throw '툴바 아이콘 이미지 파일 이름이 정의되지 않았습니다.';
  1866. }
  1867. tmpDiv.innerHTML = html;
  1868. container = tmpDiv.firstChild;
  1869. self.createEditorElement(container, toolbar);
  1870. cdata = tmpl.getElementsByTagName('PopupWindow').item(0).getElementsByTagName('Html').item(0);
  1871. html = self.getCDATASection(cdata);
  1872. tmpDiv.innerHTML = html;
  1873. popupWindow = tmpDiv.firstChild;
  1874. self.cheditor.popupElem = popupWindow;
  1875. dragHandle = popupWindow.firstChild;
  1876. self.cheditor.dragHandle = dragHandle;
  1877. self.cheditor.popupTitle = dragHandle.getElementsByTagName('label')[0];
  1878. self.cheditor.popupFrameWrapper = dragHandle.nextSibling;
  1879. container.appendChild(popupWindow);
  1880. modalFrame = document.createElement('div');
  1881. modalFrame.className = 'cheditor-modalPopupTransparent';
  1882. self.cheditor.modalBackground = modalFrame;
  1883. self.cheditor.modalBackground.id = 'popupModalBackground';
  1884. self.cheditor.modalBackground.className = 'cheditor-popupModalBackground';
  1885. container.parentNode.insertBefore(modalFrame, container);
  1886. self.cheditor.htmlEditable = document.createElement('iframe');
  1887. self.cheditor.htmlEditable.style.display = 'none';
  1888. self.cheditor.htmlEditable.style.width = '1px';
  1889. self.cheditor.htmlEditable.style.height = '1px';
  1890. self.cheditor.htmlEditable.style.visibility = 'hidden';
  1891. container.appendChild(self.cheditor.htmlEditable);
  1892. },
  1893. imageEvent: function (img, action) {
  1894. var self = this,
  1895. onMouseUpEventHandler = function () {
  1896. self.cheditor.editBlock.style.display = 'block';
  1897. self.modifyImage(this);
  1898. },
  1899. onClickEventHandler = function () {
  1900. self.cheditor.editBlock.style.display = 'block';
  1901. self.modifyImage(this);
  1902. };
  1903. if (GB.browser.msie) {
  1904. if (!action) {
  1905. img.onmouseup = null;
  1906. return;
  1907. }
  1908. (function () {
  1909. img.onmouseup = onMouseUpEventHandler;
  1910. })();
  1911. } else {
  1912. if (!action) {
  1913. self.removeEvent(img, 'click', onClickEventHandler);
  1914. return;
  1915. }
  1916. this.addEvent(img, 'click', onClickEventHandler);
  1917. }
  1918. },
  1919. setImageEvent: function (action) {
  1920. var images = this.doc.images, i,
  1921. len = images.length;
  1922. for (i = 0; i < len; i++) {
  1923. if (/icons\/em\//.test(images[i].src)) {
  1924. continue;
  1925. }
  1926. this.imageEvent(images[i], action);
  1927. }
  1928. },
  1929. run: function () {
  1930. var self = this,
  1931. showEditor = function () {
  1932. var grayImage = null;
  1933. if (!self.resetDoc()) {
  1934. return;
  1935. }
  1936. self.editAreaFocus();
  1937. self.setEditorEvent();
  1938. if (GB.browser.msie && GB.browser.version > 8 || GB.browser.a) {
  1939. grayImage = new Image();
  1940. grayImage.onload = function () {
  1941. self.cheditor.toolbarGrayscale = self.makeToolbarGrayscale(this);
  1942. self.toolbarUpdate();
  1943. };
  1944. grayImage.src = self.toolbar.icon;
  1945. grayImage.style.width = '750px'; grayImage.style.height = '16px';
  1946. } else {
  1947. self.cheditor.toolbarGrayscale = null;
  1948. self.toolbarUpdate();
  1949. }
  1950. self.setImageEvent(true);
  1951. self.removeEvent(document, self.cheditor.id, showEditor);
  1952. };
  1953. try {
  1954. this.setFolderPath();
  1955. this.checkInputForm();
  1956. }
  1957. catch (e) {
  1958. alert(e.toString());
  1959. return;
  1960. }
  1961. self.setDefaultCss({ css: 'ui.css', doc: window.document });
  1962. if (this.W3CRange) {
  1963. this.addEvent(document, this.cheditor.id, showEditor);
  1964. } else {
  1965. document.documentElement.loadEvent = 0;
  1966. document.documentElement.attachEvent('onpropertychange', function (evt) {
  1967. if (evt.propertyName === 'loadEvent') {
  1968. showEditor();
  1969. }
  1970. });
  1971. }
  1972. this.initTemplate();
  1973. },
  1974. fullScreenMode: function () {
  1975. var self = this,
  1976. container = self.cheditor.container,
  1977. windowSize, height,
  1978. child = container.firstChild,
  1979. except = 0,
  1980. editorHeight = parseInt(self.config.editorHeight, 10),
  1981. containerReSize = function () {
  1982. windowSize = self.getWindowSize();
  1983. container.style.width = windowSize.width + 'px';
  1984. if (self.cheditor.mode === 'code') {
  1985. self.resizeTextContent();
  1986. height = (windowSize.height - except - 6 - parseInt(self.cheditor.textContent.getAttribute('xbar-height'), 10));
  1987. self.cheditor.textContent.style.height = height + 'px';
  1988. }
  1989. self.cheditor.editArea.style.height = (windowSize.height - except - 6) + 'px';
  1990. },
  1991. onMouseDownEventHandler = function (evt) {
  1992. self.resizeStart(evt);
  1993. };
  1994. self.editAreaFocus();
  1995. self.boxHideAll();
  1996. self.cheditor.editArea.style.visibility = 'hidden';
  1997. if (!self.setFullScreenMode) {
  1998. container.className = 'cheditor-container-fullscreen';
  1999. if (GB.browser.msie && GB.browser.version < 7) {
  2000. self.cheditor.fullScreenFlag = document.createElement('span');
  2001. self.cheditor.fullScreenFlag.style.display = 'none';
  2002. container.parentNode.insertBefore(self.cheditor.fullScreenFlag, container);
  2003. document.body.insertBefore(container, document.body.firstChild);
  2004. }
  2005. while (child) {
  2006. if (child.className !== 'cheditor-editarea-wrapper' &&
  2007. child.className !== 'cheditor-popup-window' &&
  2008. child.className !== '') {
  2009. except += child.offsetHeight;
  2010. }
  2011. child = child.nextSibling;
  2012. }
  2013. (function () {
  2014. window.onresize = containerReSize;
  2015. })();
  2016. containerReSize();
  2017. self.cheditor.resizeBar.onmousedown = null;
  2018. self.cheditor.resizeBar.className = 'cheditor-resizebar-off';
  2019. } else {
  2020. window.onresize = null;
  2021. container.removeAttribute('style');
  2022. container.className = 'cheditor-container';
  2023. container.style.width = self.config.editorWidth;
  2024. if (self.cheditor.mode === 'code') {
  2025. height = editorHeight - parseInt(self.cheditor.textContent.getAttribute('xbar-height'), 10);
  2026. self.cheditor.textContent.style.height = height + 'px';
  2027. } else {
  2028. self.cheditor.editArea.style.height = editorHeight + 'px';
  2029. }
  2030. (function () {
  2031. self.cheditor.resizeBar.onmousedown = onMouseDownEventHandler;
  2032. })();
  2033. self.cheditor.resizeBar.className = 'cheditor-resizebar';
  2034. if (GB.browser.msie && GB.browser.version < 7) {
  2035. self.cheditor.fullScreenFlag.parentNode.replaceChild(container, self.cheditor.fullScreenFlag);
  2036. }
  2037. }
  2038. self.cheditor.editArea.style.visibility = 'visible';
  2039. self.setFullScreenMode = !(self.setFullScreenMode);
  2040. self.editAreaFocus();
  2041. },
  2042. showPulldown: function (cmd, btn) {
  2043. switch (cmd) {
  2044. case 'FontName':
  2045. this.showFontTypeMenu(btn);
  2046. break;
  2047. case 'FontSize':
  2048. this.showFontSizeMenu(btn);
  2049. break;
  2050. case 'FormatBlock':
  2051. this.showFormatBlockMenu(btn);
  2052. break;
  2053. case 'ForeColor':
  2054. case 'BackColor':
  2055. this.showColorMenu(btn);
  2056. break;
  2057. case 'TextBlock':
  2058. this.showTextBlockMenu(btn);
  2059. break;
  2060. case 'LineHeight':
  2061. this.showLineHeightMenu(btn);
  2062. break;
  2063. case 'OrderedList':
  2064. case 'UnOrderedList':
  2065. this.showOrderedListMenu(btn);
  2066. }
  2067. },
  2068. setPulldownClassName: function (labels, pNode) {
  2069. var i = 0, label;
  2070. for (; i < labels.length; i++) {
  2071. label = labels[i];
  2072. if (label.getAttribute('name') === pNode.firstChild.firstChild.firstChild.nodeValue) {
  2073. label.parentNode.style.backgroundImage = 'url(' + this.config.editorPath + 'icons/checked.png)';
  2074. label.parentNode.style.backgroundPosition = '0 center';
  2075. label.parentNode.style.backgroundRepeat = 'no-repeat';
  2076. } else {
  2077. label.parentNode.style.backgroundImage = '';
  2078. }
  2079. label.parentNode.className = 'cheditor-pulldown-mouseout';
  2080. }
  2081. },
  2082. showOrderedListMenu: function (pNode) {
  2083. var self = this,
  2084. menu = pNode.getAttribute('name'),
  2085. elem = self.pulldown[menu];
  2086. (function () {
  2087. if (!elem) {
  2088. var cmd = (menu === 'UnOrderedListCombo') ? 'InsertUnOrderedList' : 'InsertOrderedList',
  2089. outputHtml = document.createElement('div'),
  2090. onClickEventHandler = function () {
  2091. self.doCmdPopup(cmd, this.id, self.toolbar[menu].prev.checked);
  2092. },
  2093. onMouseOverEventHandler = function () {
  2094. self.pulldownMouseOver(this);
  2095. },
  2096. onMouseOutEventHandler = function () {
  2097. self.pulldownMouseOut(this);
  2098. },
  2099. list = (cmd === 'InsertUnOrderedList') ? GB.listStyle.unOrdered : GB.listStyle.ordered,
  2100. i, div, label, li, ol;
  2101. for (i in list) {
  2102. if (list.hasOwnProperty(i)) {
  2103. div = document.createElement('div');
  2104. label = document.createElement('label');
  2105. div.id = i;
  2106. (function () {
  2107. div.onclick = onClickEventHandler;
  2108. div.onmouseover = onMouseOverEventHandler;
  2109. div.onmouseout = onMouseOutEventHandler;
  2110. })();
  2111. self.pulldownMouseOut(div);
  2112. label.style.fontFamily = 'verdana';
  2113. label.style.textAlign = 'center';
  2114. label.style.width = '15px';
  2115. label.setAttribute('name', i);
  2116. li = document.createElement('li');
  2117. li.appendChild(document.createTextNode(list[i]));
  2118. ol = document.createElement('ul');
  2119. ol.style.width = '90px';
  2120. ol.style.padding = '0 15px';
  2121. ol.style.margin = '0px';
  2122. ol.style.listStyleType = i;
  2123. ol.style.cursor = 'default';
  2124. ol.style.textAlign = 'left';
  2125. ol.appendChild(li);
  2126. label.appendChild(ol);
  2127. div.appendChild(label);
  2128. outputHtml.appendChild(div);
  2129. }
  2130. }
  2131. self.createWindow(110, outputHtml);
  2132. self.createPulldownFrame(outputHtml, menu);
  2133. }
  2134. })();
  2135. self.windowPos(pNode, menu);
  2136. self.displayWindow(pNode, menu);
  2137. },
  2138. showColorMenu: function (pNode) {
  2139. var menu = pNode.getAttribute('name'),
  2140. elem = this.pulldown[menu],
  2141. selectedColor = this.colorConvert(pNode.lastChild.style.backgroundColor, 'hex'),
  2142. i, len, nodes, node, outputHtml;
  2143. if (!elem) {
  2144. outputHtml = this.setColorTable(menu);
  2145. this.createWindow(220, outputHtml);
  2146. this.createPulldownFrame(outputHtml, menu);
  2147. elem = this.pulldown[menu];
  2148. elem.firstChild.className = 'cheditor-pulldown-color-container';
  2149. }
  2150. this.toolbar[menu].colorNode.selectedValue.style.backgroundColor = selectedColor;
  2151. this.toolbar[menu].colorNode.colorPicker.hidePicker();
  2152. this.toolbar[menu].colorNode.colorPicker.fromString(selectedColor);
  2153. this.toolbar[menu].colorNode.showPicker = false;
  2154. nodes = elem.getElementsByTagName('span');
  2155. len = nodes.length;
  2156. for (i = 0; i < len; i++) {
  2157. node = nodes[i];
  2158. node.style.backgroundImage = '';
  2159. if (node.id && node.id.toLowerCase() === selectedColor.toLowerCase()) {
  2160. node.style.backgroundImage = 'url("' + this.config.iconPath + '/color_picker_tick.png")';
  2161. node.style.backgroundRepeat = 'no-repeat';
  2162. node.style.backgroundPosition = 'center center';
  2163. }
  2164. }
  2165. this.toolbar[menu].colorNode.selectedValue.style.backgroundImage = 'url("' +
  2166. this.config.iconPath + '/color_picker_tick.png")';
  2167. this.toolbar[menu].colorNode.selectedValue.style.backgroundRepeat = 'no-repeat';
  2168. this.toolbar[menu].colorNode.selectedValue.style.backgroundPosition = 'center center';
  2169. this.windowPos(pNode, menu);
  2170. this.displayWindow(pNode, menu);
  2171. },
  2172. showFontTypeMenu: function (pNode) {
  2173. var self = this,
  2174. menu = pNode.getAttribute('name'),
  2175. elem = self.pulldown[menu];
  2176. (function () {
  2177. if (!elem) {
  2178. var fonts = null, type, i, div, label,
  2179. outputHtml = self.doc.createElement('div'),
  2180. onClickEventHandler = function () {
  2181. self.doCmdPopup(menu, this.id);
  2182. },
  2183. onMouseOverEventHandler = function () {
  2184. self.pulldownMouseOver(this);
  2185. },
  2186. onMouseOutEventHandler = function () {
  2187. self.pulldownMouseOut(this);
  2188. };
  2189. for (type in GB.fontName) {
  2190. if (GB.fontName.hasOwnProperty(type)) {
  2191. fonts = GB.fontName[type];
  2192. for (i = 0; i < fonts.length; i++) {
  2193. div = self.doc.createElement('div');
  2194. label = self.doc.createElement('label');
  2195. div.id = fonts[i];
  2196. (function () {
  2197. div.onclick = onClickEventHandler;
  2198. div.onmouseover = onMouseOverEventHandler;
  2199. div.onmouseout = onMouseOutEventHandler;
  2200. })();
  2201. label.style.fontFamily = fonts[i];//(type !== 'kr') ? fonts[i] : this.config.editorFontName;
  2202. label.appendChild(self.doc.createTextNode(fonts[i]));
  2203. label.setAttribute('name', fonts[i]);
  2204. div.appendChild(label);
  2205. outputHtml.appendChild(div);
  2206. }
  2207. }
  2208. }
  2209. self.createWindow(155, outputHtml);
  2210. self.createPulldownFrame(outputHtml, menu);
  2211. elem = self.pulldown[menu];
  2212. }
  2213. })();
  2214. self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode);
  2215. self.windowPos(pNode, menu);
  2216. self.displayWindow(pNode, menu);
  2217. },
  2218. showFormatBlockMenu: function (pNode) {
  2219. var self = this,
  2220. menu = pNode.getAttribute('name'),
  2221. elem = self.pulldown[menu];
  2222. (function () {
  2223. if (!elem) {
  2224. var para, label, fontSize, div,
  2225. outputHtml = document.createElement('div'),
  2226. onClickEventHandler = function () {
  2227. self.doCmdPopup('FormatBlock', '<' + this.id + '>');
  2228. },
  2229. onMouseOverEventHandler = function () {
  2230. self.pulldownMouseOver(this);
  2231. },
  2232. onMouseOutEventHandler = function () {
  2233. self.pulldownMouseOut(this);
  2234. };
  2235. for (para in GB.formatBlock) {
  2236. if (GB.formatBlock.hasOwnProperty(para)) {
  2237. div = document.createElement('div');
  2238. div.id = para;
  2239. (function () {
  2240. div.onclick = onClickEventHandler;
  2241. div.onmouseover = onMouseOverEventHandler;
  2242. div.onmouseout = onMouseOutEventHandler;
  2243. })();
  2244. label = document.createElement('label');
  2245. if (para.match(/H[123456]/)) {
  2246. fontSize = { 'H1': '2em', 'H2': '1.5em', 'H3': '1.17em', 'H4': '1em', 'H5': '0.83em', 'H6': '0.75em' };
  2247. label.style.fontWeight = 'bold';
  2248. label.style.fontSize = fontSize[para];
  2249. label.style.lineHeight = 1.4;
  2250. } else if (para === 'ADDRESS') {
  2251. label.style.fontStyle = 'italic';
  2252. }
  2253. label.appendChild(document.createTextNode(GB.formatBlock[para]));
  2254. div.appendChild(label);
  2255. label.setAttribute('name', GB.formatBlock[para]);
  2256. outputHtml.appendChild(div);
  2257. }
  2258. }
  2259. self.createWindow(150, outputHtml);
  2260. self.createPulldownFrame(outputHtml, menu);
  2261. elem = self.pulldown[menu];
  2262. }
  2263. })();
  2264. self.setPulldownClassName(elem.firstChild.getElementsByTagName('label'), pNode);
  2265. self.windowPos(pNode, menu);
  2266. self.displayWindow(pNode, menu);
  2267. },
  2268. showFontSizeMenu: function (pNode) {
  2269. var self = this,
  2270. menu = pNode.getAttribute('name'),
  2271. elem = self.pulldown[menu];
  2272. (function () {
  2273. if (!elem) {
  2274. var size, div, label, text, i,
  2275. value = GB.fontSize[self.config.fontSizeValue],
  2276. len = value.length,
  2277. outputHtml = document.createElement('div'),
  2278. onClickEventHandler = function (e) {
  2279. self.stopEvent(e);
  2280. self.doCmdPopup(menu, this.id);
  2281. },
  2282. onMouseOverEventHandler = function () {
  2283. self.pulldownMouseOver(this);
  2284. },
  2285. onMouseOutEventHandler = function () {
  2286. self.pulldownMouseOut(this);
  2287. };
  2288. for (i = 0; i < len; i++) {
  2289. size = value[i];
  2290. div = document.createElement('div');
  2291. label = document.createElement('label');
  2292. text = size > 48 ? '가' : (size > 28 ? '가나다' : '가나다라');
  2293. size = size + self.config.fontSizeValue;
  2294. div.id = size;
  2295. (function () {
  2296. div.onclick = onClickEventHandler;
  2297. div.onmouseover = onMouseOverEventHandler;
  2298. div.onmouseout = onMouseOutEventHandler;
  2299. })();
  2300. div.style.fontSize = size;
  2301. label.style.fontFamily = self.config.editorFontName;
  2302. label.setAttribute('name', size);
  2303. label.appendChild(document.createTextNode(text + '(' + size + ')'));
  2304. div.appendChild(label);
  2305. outputHtml.appendChild(div);
  2306. }
  2307. self.createWindow(350, outputHtml);
  2308. outputHtml.style.height = '300px';
  2309. outputHtml.style.overflow = 'auto';
  2310. self.createPulldownFrame(outputHtml, menu);
  2311. elem = self.pulldown[menu];
  2312. }
  2313. })();
  2314. self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode);
  2315. self.windowPos(pNode, menu);
  2316. self.displayWindow(pNode, menu);
  2317. },
  2318. showLineHeightMenu: function (pNode) {
  2319. var self = this,
  2320. menu = pNode.getAttribute('name'),
  2321. elem = self.pulldown[menu];
  2322. (function () {
  2323. if (!elem) {
  2324. var i, div, label, text,
  2325. outputHtml = document.createElement('div'),
  2326. onClickEventHandler = function () {
  2327. self.doCmdPopup('LineHeight', this.id);
  2328. },
  2329. onMouseOverEventHandler = function () {
  2330. self.pulldownMouseOver(this);
  2331. },
  2332. onMouseOutEventHandler = function () {
  2333. self.pulldownMouseOut(this);
  2334. };
  2335. for (i in GB.lineHeight) {
  2336. if (!(GB.lineHeight.hasOwnProperty(i))) {
  2337. continue;
  2338. }
  2339. if (!GB.lineHeight[i]) {
  2340. break;
  2341. }
  2342. div = document.createElement('div');
  2343. label = document.createElement('label');
  2344. text = i;
  2345. div.id = GB.lineHeight[i];
  2346. (function () {
  2347. div.onclick = onClickEventHandler;
  2348. div.onmouseover = onMouseOverEventHandler;
  2349. div.onmouseout = onMouseOutEventHandler;
  2350. })();
  2351. label.style.fontFamily = self.config.editorFontName;
  2352. label.setAttribute('name', GB.lineHeight[i]);
  2353. label.appendChild(document.createTextNode(text));
  2354. div.appendChild(label);
  2355. outputHtml.appendChild(div);
  2356. }
  2357. self.createWindow(100, outputHtml);
  2358. self.createPulldownFrame(outputHtml, menu);
  2359. elem = self.pulldown[menu];
  2360. }
  2361. })();
  2362. self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode);
  2363. self.windowPos(pNode, menu);
  2364. self.displayWindow(pNode, menu);
  2365. },
  2366. showTextBlockMenu: function (pNode) {
  2367. var self = this,
  2368. menu = pNode.getAttribute('name'),
  2369. elem = self.pulldown[menu];
  2370. (function () {
  2371. if (!elem) {
  2372. var i, wrapper, div, label,
  2373. outputHtml = document.createElement('div'),
  2374. onClickEventHandler = function () {
  2375. self.boxStyle(this);
  2376. },
  2377. onMouseOverEventHandler = function () {
  2378. this.className = 'cheditor-pulldown-textblock-over';
  2379. },
  2380. onMouseOutEventHandler = function () {
  2381. this.className = 'cheditor-pulldown-textblock-out';
  2382. },
  2383. quote = GB.textBlock;
  2384. for (i = 0; i < quote.length; i++) {
  2385. wrapper = document.createElement('div');
  2386. div = document.createElement('div');
  2387. (function () {
  2388. div.onclick = onClickEventHandler;
  2389. wrapper.onmouseover = onMouseOverEventHandler;
  2390. wrapper.onmouseout = onMouseOutEventHandler;
  2391. })();
  2392. wrapper.className = 'cheditor-pulldown-textblock-out';
  2393. div.id = i;
  2394. div.style.border = quote[i][0];
  2395. div.style.backgroundColor = quote[i][1];
  2396. div.style.fontFamily = self.config.editorFontName;
  2397. label = document.createElement('label');
  2398. label.appendChild(document.createTextNode('가나다라 ABC'));
  2399. div.appendChild(label);
  2400. wrapper.appendChild(div);
  2401. outputHtml.appendChild(wrapper);
  2402. }
  2403. self.createWindow(160, outputHtml);
  2404. self.createPulldownFrame(outputHtml, menu);
  2405. elem = self.pulldown[menu];
  2406. elem.firstChild.className = 'cheditor-pulldown-textblock-container';
  2407. }
  2408. })();
  2409. self.windowPos(pNode, menu);
  2410. self.displayWindow(pNode, menu);
  2411. },
  2412. createPulldownFrame: function (contents, id) {
  2413. var div = document.createElement('div');
  2414. div.className = 'cheditor-pulldown-frame';
  2415. div.appendChild(contents);
  2416. this.pulldown[id] = div;
  2417. this.cheditor.container.firstChild.appendChild(div);
  2418. },
  2419. setDefaultCss: function (ar) {
  2420. var cssFile, head, found = false, children, i, href, css;
  2421. ar = ar || { css: 'editarea.css', doc: this.doc };
  2422. cssFile = this.config.cssPath + ar.css;
  2423. head = ar.doc.getElementsByTagName('head')[0];
  2424. if (this.undefined(head)) {
  2425. return;
  2426. }
  2427. if (head.hasChildNodes()) {
  2428. children = head.childNodes;
  2429. for (i = 0; i < children.length; i++) {
  2430. if (children[i].nodeName.toLowerCase() === 'link') {
  2431. href = children[i].getAttribute('href');
  2432. if (href && href === cssFile) {
  2433. found = true;
  2434. break;
  2435. }
  2436. }
  2437. }
  2438. }
  2439. if (!found) {
  2440. css = head.appendChild(ar.doc.createElement('link'));
  2441. css.setAttribute('type', 'text/css');
  2442. css.setAttribute('rel', 'stylesheet');
  2443. css.setAttribute('media', 'all');
  2444. css.setAttribute('href', this.config.cssPath + ar.css);
  2445. }
  2446. },
  2447. setEditorEvent: function () {
  2448. var self = this,
  2449. onKeyDownEventHandler = function (evt) {
  2450. if (self.cheditor.mode === 'preview') {
  2451. self.stopEvent(evt);
  2452. return;
  2453. }
  2454. self.doOnKeyDown(evt);
  2455. },
  2456. onKeyPressEventHandler = function (evt) {
  2457. if (self.cheditor.mode === 'preview') {
  2458. self.stopEvent(evt);
  2459. return;
  2460. }
  2461. self.doOnKeyPress(evt);
  2462. },
  2463. onKeyUpEventHandler = function (evt) {
  2464. if (self.cheditor.mode === 'preview') {
  2465. self.stopEvent(evt);
  2466. return;
  2467. }
  2468. self.doOnKeyUp(evt);
  2469. },
  2470. onMouseUpEventHandler = function (evt) {
  2471. if (self.cheditor.mode === 'rich') {
  2472. if (evt.clientX <= self.doc.body.offsetWidth) {
  2473. self.doEditorEvent(evt);
  2474. } else {
  2475. self.restoreRange();
  2476. }
  2477. return;
  2478. }
  2479. if (self.cheditor.mode === 'preview') {
  2480. self.stopEvent(evt);
  2481. }
  2482. },
  2483. onMouseDownEventHandler = function (evt) {
  2484. if (self.cheditor.mode === 'rich') {
  2485. if (evt.clientX <= self.doc.body.offsetWidth) {
  2486. // self.clearSelection();
  2487. } else {
  2488. self.backupRange();
  2489. }
  2490. self.boxHideAll();
  2491. return;
  2492. }
  2493. if (self.cheditor.mode === 'preview') {
  2494. self.stopEvent(evt);
  2495. }
  2496. };
  2497. (function () {
  2498. self.addEvent(self.doc, 'keydown', onKeyDownEventHandler);
  2499. self.addEvent(self.doc, 'keypress', onKeyPressEventHandler);
  2500. self.addEvent(self.doc, 'keyup', onKeyUpEventHandler);
  2501. self.addEvent(self.doc, 'mouseup', onMouseUpEventHandler);
  2502. self.addEvent(self.doc, 'mousedown', onMouseDownEventHandler);
  2503. })();
  2504. },
  2505. addEvent: function (evTarget, evType, evHandler) {
  2506. if (evTarget.addEventListener) {
  2507. evTarget.addEventListener(evType, evHandler, false);
  2508. } else {
  2509. evTarget.attachEvent('on' + evType, evHandler);
  2510. }
  2511. },
  2512. removeEvent: function (elem, ev, func) {
  2513. if (elem.removeEventListener) {
  2514. elem.removeEventListener(ev, func, false);
  2515. } else {
  2516. elem.detachEvent('on' + ev, func);
  2517. }
  2518. },
  2519. stopEvent: function (ev) {
  2520. if (ev && ev.preventDefault) {
  2521. ev.preventDefault();
  2522. ev.stopPropagation();
  2523. } else {
  2524. ev = ev || window.event;
  2525. ev.cancelBubble = true;
  2526. ev.returnValue = false;
  2527. }
  2528. },
  2529. toolbarButtonOut: function (elemButton, nTop) {
  2530. elemButton.style.top = -nTop + 'px';
  2531. },
  2532. toolbarButtonOver: function (elemButton) {
  2533. var nTop = elemButton.style.top.substring(0, elemButton.style.top.length - 2);
  2534. elemButton.style.top = nTop - 22 + 'px';
  2535. },
  2536. getElement: function (elem, tag) {
  2537. if (!elem || !tag) {
  2538. return null;
  2539. }
  2540. while (elem && elem.nodeName.toLowerCase() !== tag.toLowerCase()) {
  2541. if (elem.nodeName.toLowerCase() === 'body') {
  2542. break;
  2543. }
  2544. elem = elem.parentNode;
  2545. }
  2546. return elem;
  2547. },
  2548. hyperLink: function (href, target, title) {
  2549. var self = this,
  2550. links = null, i,
  2551. createLinks = function () {
  2552. var range = self.restoreRange(),
  2553. selectedLinks = [],
  2554. linkRange = self.createRange(), selection = null, container = null, k;
  2555. self.backupRange(range);
  2556. if (self.W3CRange) {
  2557. self.doc.execCommand("CreateLink", false, href);
  2558. selection = self.getSelection();
  2559. for (i = 0; i < selection.rangeCount; ++i) {
  2560. range = selection.getRangeAt(i);
  2561. container = range.commonAncestorContainer;
  2562. if (self.getSelectionType(range) === GB.selection.text) {
  2563. container = container.parentNode;
  2564. }
  2565. if (container.nodeName.toLowerCase() === 'a') {
  2566. selectedLinks.push(container);
  2567. } else {
  2568. links = container.getElementsByTagName('a');
  2569. for (k = 0; k < links.length; ++k) {
  2570. linkRange.selectNodeContents(links[k]);
  2571. if (linkRange.compareBoundaryPoints(range.END_TO_START, range) < 1 &&
  2572. linkRange.compareBoundaryPoints(range.START_TO_END, range) > -1) {
  2573. selectedLinks.push(links[k]);
  2574. }
  2575. }
  2576. }
  2577. }
  2578. linkRange.detach();
  2579. } else {
  2580. range = self.doc.selection.createRange();
  2581. range.execCommand("UnLink", false);
  2582. range.execCommand("CreateLink", false, href);
  2583. switch (self.getSelectionType(range)) {
  2584. case GB.selection.text:
  2585. container = range.parentElement();
  2586. break;
  2587. case GB.selection.element:
  2588. container = range.item(0).parentNode;
  2589. break;
  2590. default: return null;
  2591. }
  2592. if (container.nodeName.toLowerCase() === 'a') {
  2593. selectedLinks.push(container);
  2594. } else {
  2595. links = container.getElementsByTagName('a');
  2596. for (i = 0; i < links.length; ++i) {
  2597. linkRange.moveToElementText(links[i]);
  2598. if (linkRange.compareEndPoints("StartToEnd", range) > -1 &&
  2599. linkRange.compareEndPoints("EndToStart", range) < 1) {
  2600. selectedLinks.push(links[i]);
  2601. }
  2602. }
  2603. }
  2604. }
  2605. return selectedLinks;
  2606. };
  2607. this.editArea.focus();
  2608. links = createLinks();
  2609. if (links) {
  2610. for (i = 0; i < links.length; ++i) {
  2611. if (target) {
  2612. links[i].setAttribute("target", target);
  2613. }
  2614. if (title) {
  2615. links[i].setAttribute("title", title);
  2616. }
  2617. }
  2618. }
  2619. },
  2620. getOffsetBox: function (el) {
  2621. var box = el.getBoundingClientRect(),
  2622. doc = this.doc.documentElement,
  2623. body = this.doc.body,
  2624. scrollTop = doc.scrollTop || body.scrollTop,
  2625. scrollLeft = doc.scrollLeft || body.scrollLeft,
  2626. clientTop = doc.clientTop || body.clientTop || 0,
  2627. clientLeft = doc.clientLeft || body.clientLeft || 0,
  2628. top = box.top + scrollTop - clientTop,
  2629. left = box.left + scrollLeft - clientLeft;
  2630. return { top: Math.round(top), left: Math.round(left) };
  2631. },
  2632. makeSpacerElement: function () {
  2633. var elem,
  2634. para = this.doc.createElement('p');
  2635. if (GB.browser.msie && GB.browser.version < 11 && GB.browser.version > 8) {
  2636. elem = this.doc.createComment(this.cheditor.bogusSpacerName);
  2637. } else if (GB.browser.msie_c) {
  2638. elem = this.createNbspTextNode();
  2639. } else {
  2640. elem = this.doc.createElement('br');
  2641. elem.className = this.cheditor.bogusSpacerName;
  2642. }
  2643. para.appendChild(elem);
  2644. return para;
  2645. },
  2646. boxStyle: function (el) {
  2647. var range, elem, ctx, textRange, frag, pNode,
  2648. blockQuote = this.doc.createElement('blockquote'),
  2649. para = null;
  2650. this.editAreaFocus();
  2651. range = this.range || this.getRange()
  2652. blockQuote.style.border = GB.textBlock[el.id][0];
  2653. blockQuote.style.backgroundColor = GB.textBlock[el.id][1];
  2654. blockQuote.style.padding = '5px 10px';
  2655. if (!this.W3CRange) {
  2656. ctx = range.htmlText;
  2657. blockQuote.innerHTML = ctx || '&nbsp;';
  2658. range.select();
  2659. this.insertHTML(blockQuote);
  2660. textRange = this.getRange();
  2661. elem = range.parentElement();
  2662. textRange.moveToElementText(elem);
  2663. textRange.collapse(false);
  2664. textRange.select();
  2665. } else {
  2666. try {
  2667. frag = range.extractContents();
  2668. if (!frag.firstChild) {
  2669. para = this.makeSpacerElement();
  2670. blockQuote.appendChild(para);
  2671. } else {
  2672. blockQuote.appendChild(frag);
  2673. }
  2674. range.insertNode(blockQuote);
  2675. pNode = blockQuote.parentNode;
  2676. while (pNode && pNode.nodeName.toLowerCase() !== 'body') {
  2677. if (pNode.nodeName.toLowerCase() === 'p' || pNode.nodeName.toLowerCase() === 'div') {
  2678. pNode.parentNode.insertBefore(blockQuote, pNode.nextSibling);
  2679. break;
  2680. }
  2681. pNode = pNode.parentNode;
  2682. }
  2683. this.placeCaretAt(para || blockQuote, false);
  2684. } catch (ignore) {
  2685. // --
  2686. }
  2687. }
  2688. this.boxHideAll();
  2689. },
  2690. insertFlash: function (elem) {
  2691. var embed = null, pos, str, obj, child, movieHeight, params = [], movieWidth, i,
  2692. div = this.doc.createElement('div');
  2693. this.editAreaFocus();
  2694. this.restoreRange();
  2695. if (typeof elem === 'string') {
  2696. elem = this.trimSpace(elem);
  2697. pos = elem.toLowerCase().indexOf('embed');
  2698. if (pos !== -1) {
  2699. str = elem.substr(pos);
  2700. pos = str.indexOf('>');
  2701. div.innerHTML = '<' + str.substr(0, pos) + '>';
  2702. embed = div.firstChild;
  2703. } else {
  2704. div.innerHTML = elem;
  2705. obj = div.getElementsByTagName('object')[0];
  2706. if (obj && obj.hasChildNodes()) {
  2707. child = obj.firstChild;
  2708. movieWidth = (isNaN(obj.width) !== true) ? obj.width : 320;
  2709. movieHeight = (isNaN(obj.height) !== true) ? obj.height : 240;
  2710. do {
  2711. if ((child.nodeName.toLowerCase() === 'param') &&
  2712. (!this.undefined(child.name) && !this.undefined(child.value))) {
  2713. params.push({ key: (child.name === 'movie') ? 'src' : child.name, val: child.value });
  2714. }
  2715. child = child.nextSibling;
  2716. } while (child);
  2717. if (params.length > 0) {
  2718. embed = this.doc.createElement('embed');
  2719. embed.setAttribute('width', movieWidth);
  2720. embed.setAttribute('height', movieHeight);
  2721. for (i = 0; i < params.length; i++) {
  2722. embed.setAttribute(params[i].key, params[i].val);
  2723. }
  2724. embed.setAttribute('type', 'application/x-shockwave-flash');
  2725. }
  2726. }
  2727. }
  2728. if (embed) {
  2729. if (this.W3CRange) {
  2730. this.insertNodeAtSelection(embed);
  2731. } else {
  2732. this.doCmdPaste(embed.outerHTML);
  2733. }
  2734. }
  2735. }
  2736. },
  2737. insertHtmlPopup: function (elem) {
  2738. this.editAreaFocus();
  2739. this.restoreRange();
  2740. if (!this.W3CRange) {
  2741. this.doCmdPaste((this.toType(elem) === 'string') ? elem : elem.outerHTML);
  2742. } else {
  2743. this.insertNodeAtSelection(elem);
  2744. }
  2745. this.clearStoredSelections();
  2746. },
  2747. insertHTML: function (html) {
  2748. if (!this.W3CRange) {
  2749. this.getRange().pasteHTML((this.toType(html) === 'string') ? html : html.outerHTML);
  2750. } else {
  2751. this.insertNodeAtSelection(html);
  2752. }
  2753. },
  2754. placeCaretAt: function (elem, az) {
  2755. var range = this.createRange(),
  2756. selection = this.getSelection();
  2757. if (this.undefined(az)) {
  2758. az = false;
  2759. }
  2760. if (this.W3CRange) {
  2761. selection.removeAllRanges();
  2762. try {
  2763. if (elem.lastChild && elem.lastChild.nodeName.toLowerCase() === 'br') {
  2764. az = true;
  2765. }
  2766. range.selectNodeContents(elem);
  2767. } catch (e) {
  2768. range.selectNode(elem);
  2769. }
  2770. range.collapse(az);
  2771. try {
  2772. selection.addRange(range);
  2773. } catch (e) {
  2774. this.placeCaretAt(this.doc.body, az);
  2775. }
  2776. } else if (elem.nodeType === GB.node.element) {
  2777. range.moveToElementText(elem);
  2778. range.collapse(az);
  2779. range.select();
  2780. }
  2781. },
  2782. selectNodeContents: function (node, pos) {
  2783. var collapsed = !this.undefined(pos),
  2784. selection = this.getSelection(),
  2785. range = this.getRange();
  2786. if (node.nodeType === GB.node.element) {
  2787. range.selectNode(node);
  2788. if (collapsed) {
  2789. range.collapse(pos);
  2790. }
  2791. }
  2792. selection.removeAllRanges();
  2793. selection.addRange(range);
  2794. return range;
  2795. },
  2796. insertNodeAtSelection: function (insertNode) {
  2797. var range = this.getRange(),
  2798. selection = this.getSelection(),
  2799. frag = this.doc.createDocumentFragment(),
  2800. lastNode = null,
  2801. elem, commonAncestorContainer, startOffset, pNode, tmpWrapper;
  2802. if (!range.collapsed) {
  2803. range.deleteContents();
  2804. range = this.getRange();
  2805. }
  2806. commonAncestorContainer = range.commonAncestorContainer;
  2807. startOffset = range.startOffset;
  2808. pNode = commonAncestorContainer;
  2809. if (pNode.nodeType === GB.node.text) {
  2810. pNode = pNode.parentNode;
  2811. }
  2812. this.removeBogusSpacer(pNode);
  2813. if (typeof insertNode === 'string') {
  2814. tmpWrapper = this.doc.createElement('div');
  2815. tmpWrapper.innerHTML = insertNode;
  2816. elem = tmpWrapper.firstChild;
  2817. while (elem) {
  2818. lastNode = frag.appendChild(elem);
  2819. elem = tmpWrapper.firstChild;
  2820. }
  2821. } else {
  2822. lastNode = frag.appendChild(insertNode);
  2823. }
  2824. if (startOffset < 1 && commonAncestorContainer.nodeType === GB.node.text) {
  2825. commonAncestorContainer.parentNode.insertBefore(frag, commonAncestorContainer);
  2826. } else {
  2827. range.insertNode(frag);
  2828. }
  2829. if (lastNode) {
  2830. range = range.cloneRange();
  2831. range.setStartAfter(lastNode);
  2832. selection.removeAllRanges();
  2833. selection.addRange(range);
  2834. }
  2835. this.toolbarUpdate();
  2836. return lastNode;
  2837. },
  2838. findBogusSpacer: function (elem, all) {
  2839. var self = this, result = [];
  2840. (function findBogusSpacer(elem) {
  2841. var i = 0, node;
  2842. for (; i < elem.childNodes.length; i++) {
  2843. node = elem.childNodes[i];
  2844. if ((node.nodeType === GB.node.element && node.className === self.cheditor.bogusSpacerName) ||
  2845. (node.nodeType === GB.node.comment && node.nodeValue === self.cheditor.bogusSpacerName)) {
  2846. result.push(node);
  2847. }
  2848. if (node.nodeType === GB.node.text && node.nodeValue === '\u00a0' && !node.nextSibling) {
  2849. result.push(node);
  2850. }
  2851. if (all) {
  2852. findBogusSpacer(node);
  2853. }
  2854. }
  2855. })(elem);
  2856. return result;
  2857. },
  2858. removeBogusSpacer: function (elem, removeEmpty, all) {
  2859. var remove = this.findBogusSpacer(elem, all), i = 0;
  2860. for (; i < remove.length; i++) {
  2861. remove[i].parentNode.removeChild(remove[i]);
  2862. }
  2863. if (removeEmpty && !(elem.hasChildNodes())) {
  2864. elem.parentNode.removeChild(elem);
  2865. }
  2866. },
  2867. ieGetRangeAt: function (range) {
  2868. var self = this, start = {}, end = {};
  2869. function convert(result, bStart) {
  2870. var point = range.duplicate(),
  2871. span = self.doc.createElement('span'),
  2872. parent = point.parentElement(),
  2873. cursor = self.createRange(),
  2874. compareStr = bStart ? 'StartToStart' : 'StartToEnd';
  2875. point.collapse(bStart);
  2876. parent.appendChild(span);
  2877. cursor.moveToElementText(span);
  2878. while (cursor.compareEndPoints(compareStr, point) > 0 && span.previousSibling) {
  2879. parent.insertBefore(span, span.previousSibling);
  2880. cursor.moveToElementText(span);
  2881. }
  2882. result.container = span.nextSibling || span.previousSibling;
  2883. if (result.container === null) {
  2884. result.container = span.parentNode;
  2885. }
  2886. parent.removeChild(span);
  2887. }
  2888. convert(start, true); convert(end, false);
  2889. return { startContainer: start.container, endContainer: end.container };
  2890. },
  2891. applyLineHeight: function (opt) {
  2892. var range = this.getRange(),
  2893. isBlockElement = function (elem) {
  2894. return GB.lineHeightBlockTags[elem.toLowerCase()];
  2895. },
  2896. getNextLeaf = function (elem, endLeaf, value) {
  2897. while (!elem.nextSibling) {
  2898. elem = elem.parentNode;
  2899. if (!elem) {
  2900. return elem;
  2901. }
  2902. }
  2903. if (elem === endLeaf) {
  2904. return elem;
  2905. }
  2906. var leaf = elem.nextSibling;
  2907. if (isBlockElement(leaf.nodeName)) {
  2908. leaf.style.lineHeight = value;
  2909. }
  2910. while (leaf.firstChild) {
  2911. leaf = leaf.firstChild;
  2912. if (leaf.nodeType !== GB.node.text && isBlockElement(leaf.nodeName)) {
  2913. leaf.style.lineHeight = value;
  2914. }
  2915. }
  2916. return leaf;
  2917. },
  2918. applyBlockElement = function (elem) {
  2919. while (elem) {
  2920. if (elem.nodeName.toLowerCase() === "body") {
  2921. para = self.doc.createElement("p");
  2922. para.style.lineHeight = opt;
  2923. if (elem.firstChild) {
  2924. elem.insertBefore(para, elem.firstChild);
  2925. } else {
  2926. elem.appendChild(para);
  2927. break;
  2928. }
  2929. nextNode = para.nextSibling;
  2930. while (nextNode) {
  2931. if (isBlockElement(nextNode.nodeName)) {
  2932. break;
  2933. }
  2934. para.appendChild(nextNode);
  2935. nextNode = para.nextSibling;
  2936. }
  2937. break;
  2938. }
  2939. if (isBlockElement(elem.nodeName)) {
  2940. elem.style.lineHeight = opt;
  2941. break;
  2942. }
  2943. elem = elem.parentNode;
  2944. }
  2945. },
  2946. ieRange, startContainer, endContainer, para, nextNode, startLeaf, endLeaf, nextLeaf;
  2947. if (!this.W3CRange) {
  2948. ieRange = this.ieGetRangeAt(range);
  2949. startContainer = ieRange.startContainer;
  2950. endContainer = ieRange.endContainer;
  2951. } else {
  2952. startContainer = range.startContainer;
  2953. endContainer = range.endContainer;
  2954. }
  2955. if (!this.doc.body.hasChildNodes() || !startContainer || !endContainer) {
  2956. throw "Object Error";
  2957. }
  2958. if (startContainer && startContainer.nodeName.toLowerCase() === "body") {
  2959. startContainer = startContainer.firstChild;
  2960. }
  2961. try {
  2962. if (startContainer === endContainer) {
  2963. applyBlockElement(startContainer);
  2964. } else {
  2965. startLeaf = startContainer;
  2966. while (startLeaf) {
  2967. if (startLeaf.nodeName.toLowerCase() === "body" || isBlockElement(startLeaf.nodeName)) {
  2968. break;
  2969. }
  2970. startLeaf = startLeaf.parentNode;
  2971. }
  2972. endLeaf = endContainer;
  2973. while (endLeaf) {
  2974. if (endLeaf.nodeName.toLowerCase() === "body" || isBlockElement(endLeaf.nodeName)) {
  2975. break;
  2976. }
  2977. endLeaf = endLeaf.parentNode;
  2978. }
  2979. if (startLeaf === endLeaf) {
  2980. if (isBlockElement(startLeaf.nodeName)) {
  2981. startLeaf.style.lineHeight = opt;
  2982. } else {
  2983. para = this.doc.createElement("p");
  2984. para.style.lineHeight = opt;
  2985. startLeaf.insertBefore(para, startLeaf.firstChild);
  2986. nextNode = para.nextSibling;
  2987. while (nextNode) {
  2988. if (isBlockElement(nextNode.nodeName)) {
  2989. break;
  2990. }
  2991. para.appendChild(nextNode);
  2992. nextNode = para.nextSibling;
  2993. }
  2994. }
  2995. } else {
  2996. applyBlockElement(startLeaf);
  2997. while (startLeaf) {
  2998. nextLeaf = getNextLeaf(startLeaf, endLeaf, opt);
  2999. if (startLeaf === endLeaf) {
  3000. break;
  3001. }
  3002. startLeaf = nextLeaf;
  3003. }
  3004. }
  3005. }
  3006. } catch (ignore) {
  3007. // --
  3008. }
  3009. },
  3010. doInsertImage: function (imgs, para, insertSpace) {
  3011. var range, i, count = 0, imgAttr, img, space, lastNode = null, pNode, div, selection,
  3012. len = imgs.length, self = this,
  3013. fragment = this.doc.createDocumentFragment();
  3014. function checkPara(pNode) {
  3015. var result = true, text;
  3016. if (!pNode.hasChildNodes()) {
  3017. return false;
  3018. }
  3019. self.getNodeTree(pNode, function (node) {
  3020. if (!node.node || node === pNode) {
  3021. return;
  3022. }
  3023. if (node.type === GB.node.text) {
  3024. text = self.trimSpace(node.node.nodeValue);
  3025. if (!text || text === '\u00a0') {
  3026. result = false;
  3027. }
  3028. } else if (node.type === GB.node.element
  3029. && (node.name === 'br' && node.node.className === self.cheditor.bogusSpacerName)) {
  3030. result = false;
  3031. }
  3032. });
  3033. return result;
  3034. }
  3035. this.editAreaFocus();
  3036. range = this.restoreRange();
  3037. pNode = this.getRangeElement(range);
  3038. if (!pNode) {
  3039. return;
  3040. }
  3041. if (pNode.nodeName.toLowerCase() === 'body') {
  3042. pNode = this.doc.createElement('p');
  3043. if (this.W3CRange) {
  3044. range.insertNode(pNode);
  3045. } else {
  3046. range.pasteHTML(pNode.outerHTML);
  3047. }
  3048. }
  3049. if (para) {
  3050. do {
  3051. if (GB.lineHeightBlockTags[pNode.nodeName.toLowerCase()]) {
  3052. break;
  3053. }
  3054. pNode = pNode.parentNode;
  3055. } while (pNode && pNode.nodeName.toLowerCase() !== 'body');
  3056. }
  3057. for (i in imgs) {
  3058. if (!imgs.hasOwnProperty(i) || this.undefined(imgs[i])) {
  3059. continue;
  3060. }
  3061. imgAttr = imgs[i];
  3062. img = this.doc.createElement('img');
  3063. img.setAttribute('src', imgAttr.fileUrl);
  3064. if (this.config.imgSetAttrWidth === 1) {
  3065. img.style.width = imgAttr.width;
  3066. img.style.height = imgAttr.height;
  3067. } else if (this.config.imgSetAttrWidth === -1) {
  3068. img.style.width = '100%';
  3069. img.style.height = 'auto';
  3070. }
  3071. if (this.config.imgSetAttrAlt) {
  3072. img.setAttribute('alt', imgAttr.alt || imgAttr.origName);
  3073. } else {
  3074. img.removeAttribute('alt');
  3075. }
  3076. count++;
  3077. if (para) {
  3078. lastNode = fragment.appendChild(this.doc.createElement('p'));
  3079. if (imgAttr.align !== 'left') {
  3080. lastNode.style.textAlign = imgAttr.align;
  3081. }
  3082. lastNode.appendChild(img);
  3083. if (insertSpace && count < len) {
  3084. space = this.makeSpacerElement();
  3085. fragment.appendChild(space);
  3086. }
  3087. } else {
  3088. lastNode = fragment.appendChild(img);
  3089. if (insertSpace && count < len) {
  3090. fragment.appendChild(this.doc.createTextNode('\u00a0'));
  3091. }
  3092. }
  3093. this.images.push(imgAttr);
  3094. }
  3095. if (lastNode) {
  3096. if (para) {
  3097. if (pNode.nodeName.toLowerCase() === 'p') {
  3098. if (!checkPara(pNode)) {
  3099. pNode.parentNode.replaceChild(fragment, pNode);
  3100. } else {
  3101. pNode.parentNode.insertBefore(fragment, pNode.nextSibling);
  3102. }
  3103. } else {
  3104. if (!this.W3CRange) {
  3105. div = this.doc.createElement('div');
  3106. div.appendChild(fragment);
  3107. range.pasteHTML(div.innerHTML);
  3108. } else {
  3109. range.insertNode(fragment);
  3110. }
  3111. }
  3112. this.placeCaretAt(lastNode.nextSibling ? lastNode.nextSibling : lastNode, false);
  3113. } else {
  3114. if (!this.W3CRange) {
  3115. div = this.doc.createElement('div');
  3116. div.appendChild(fragment);
  3117. range.pasteHTML(div.innerHTML);
  3118. } else {
  3119. range.deleteContents();
  3120. range.insertNode(fragment);
  3121. range.setStartAfter(lastNode);
  3122. range.setEndAfter(lastNode);
  3123. selection = this.getSelection();
  3124. selection.removeAllRanges();
  3125. selection.addRange(range);
  3126. }
  3127. }
  3128. this.setImageEvent(true);
  3129. }
  3130. },
  3131. showTagSelector: function (on) {
  3132. if (this.config.showTagPath !== true) {
  3133. return;
  3134. }
  3135. this.cheditor.tagPath.style.display = on ? 'block' : 'none';
  3136. },
  3137. getTextContentSelectionPos: function (newline) {
  3138. var textContent = this.cheditor.textContent,
  3139. start, end, docRange, startRange, endRange, textContentLength, normalizedText;
  3140. if (typeof textContent.selectionStart === 'number') {
  3141. start = textContent.selectionStart;
  3142. end = textContent.selectionEnd;
  3143. } else {
  3144. textContentLength = textContent.value.length;
  3145. normalizedText = textContent.value.replace(/\r\n/g, '\n');
  3146. docRange = document.selection.createRange();
  3147. startRange = textContent.createTextRange();
  3148. endRange = startRange.duplicate();
  3149. endRange.collapse(false);
  3150. startRange.moveToBookmark(docRange.getBookmark());
  3151. if (startRange.compareEndPoints('StartToEnd', endRange) > -1) {
  3152. start = end = textContentLength;
  3153. } else {
  3154. start = -startRange.moveStart('character', -textContentLength);
  3155. if (newline) {
  3156. start += normalizedText.slice(0, start).split('\n').length - 1;
  3157. }
  3158. if (startRange.compareEndPoints('EndToEnd', endRange) > -1) {
  3159. end = textContentLength;
  3160. } else {
  3161. end = -startRange.moveEnd('character', -textContentLength);
  3162. if (newline) {
  3163. end += normalizedText.slice(0, end).split('\n').length - 1;
  3164. }
  3165. }
  3166. }
  3167. }
  3168. return { startPos: start, endPos: end };
  3169. },
  3170. removeEmptyBogusTag: function (content) {
  3171. if (/^<(p|div)([^>]+?)?>(&nbsp;|\s+?)<\/(p|div)>$/g.test(this.trimSpace(content))) {
  3172. return '';
  3173. }
  3174. if (/^<br([^>]+?)?>$/g.test(content)) {
  3175. return '';
  3176. }
  3177. return content;
  3178. },
  3179. setTextContentSelection: function (startPos, endPos, content) {
  3180. var textContent = this.cheditor.textContent, range, top;
  3181. content = this.removeEmptyBogusTag(content);
  3182. if (!content) {
  3183. textContent.focus();
  3184. return;
  3185. }
  3186. if (startPos === 0 && endPos === 0) {
  3187. textContent.value = content;
  3188. textContent.focus();
  3189. return;
  3190. }
  3191. textContent.select();
  3192. if (typeof textContent.setSelectionRange === 'function') {
  3193. textContent.value = content;
  3194. textContent.setSelectionRange(startPos, startPos);
  3195. textContent.focus();
  3196. if (this.browser.msie || this.browser.edge) {
  3197. setTimeout(function () {
  3198. top = textContent.scrollTop;
  3199. if (top > 0) {
  3200. textContent.scrollTop = top + textContent.clientHeight / 2;
  3201. }
  3202. textContent.selectionEnd = endPos;
  3203. }, 0);
  3204. } else {
  3205. textContent.selectionEnd = endPos;
  3206. }
  3207. } else {
  3208. range = document.selection.createRange();
  3209. textContent.value = content;
  3210. range.moveEnd('character', endPos - content.length);
  3211. range.moveStart('character', startPos);
  3212. range.select();
  3213. top = textContent.scrollTop;
  3214. if (top > 0) {
  3215. textContent.scrollTop = top + textContent.clientHeight / 2;
  3216. }
  3217. }
  3218. },
  3219. richMode: function () {
  3220. var char, collapsed, cursor, endNode, endPos, endRange, outputHTML = null, pNode, pos, range,
  3221. scrollTop, selection, startNode, startPos, startRange, textContent = null, textContentLength;
  3222. if (this.cheditor.mode === 'code' && typeof this.resizeTextContent !== 'undefined') {
  3223. this.cheditor.textContent.focus();
  3224. textContent = this.makeHtmlContent();
  3225. textContentLength = textContent.length;
  3226. pos = this.getTextContentSelectionPos(true);
  3227. startPos = pos.startPos;
  3228. endPos = pos.endPos;
  3229. collapsed = startPos === endPos;
  3230. cursor = startPos;
  3231. if (textContent.charAt(startPos) === '>') {
  3232. startPos++;
  3233. collapsed = true;
  3234. } else {
  3235. while (cursor > -1) {
  3236. char = textContent.charAt(cursor);
  3237. if (char === '&'
  3238. && textContent.charAt(cursor + 1) === 'n' && textContent.charAt(cursor + 2) === 'b'
  3239. && textContent.charAt(cursor + 3) === 's' && textContent.charAt(cursor + 4) === 'p'
  3240. && textContent.charAt(cursor + 5) === ';') {
  3241. startPos = cursor;
  3242. collapsed = endPos < (startPos + 6);
  3243. break;
  3244. }
  3245. if (char === '>') {
  3246. break;
  3247. }
  3248. if (char === '<') {
  3249. startPos = cursor;
  3250. collapsed = true;
  3251. break;
  3252. }
  3253. cursor--;
  3254. }
  3255. }
  3256. if (!collapsed) {
  3257. cursor = endPos;
  3258. if (textContent.charAt(endPos - 1) === '<' ||
  3259. (textContent.charAt(endPos) === '\n' && cursor === textContentLength - 1)) {
  3260. endPos = startPos;
  3261. } else {
  3262. while (cursor < textContentLength) {
  3263. char = textContent.charAt(cursor);
  3264. if (char === '<') {
  3265. break;
  3266. }
  3267. if (char === '>') {
  3268. endPos = startPos;
  3269. break;
  3270. }
  3271. cursor++;
  3272. }
  3273. }
  3274. } else {
  3275. endPos = startPos;
  3276. }
  3277. if (startPos > 0 && endPos < textContentLength - 1) {
  3278. outputHTML = textContent.substring(0, startPos);
  3279. outputHTML += '<span id="startBogusNode"></span>';
  3280. outputHTML += textContent.substring(startPos, endPos);
  3281. outputHTML += '<span id="endBogusNode"></span>';
  3282. outputHTML += textContent.substring(endPos, textContent.length);
  3283. textContent = outputHTML;
  3284. }
  3285. this.cheditor.textContent.value = '';
  3286. this.removeEvent(window, 'resize', this.resizeTextContent);
  3287. this.putContents(this.convertContentsSpacer(textContent));
  3288. }
  3289. this.range = null;
  3290. this.cheditor.textContent.blur();
  3291. this.cheditor.textContent.removeAttribute('start-pos');
  3292. this.cheditor.textContent.removeAttribute('end-pos');
  3293. this.cheditor.textContent.style.display = 'none';
  3294. this.cheditor.toolbarWrapper.style.display = '';
  3295. this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper';
  3296. this.cheditor.editArea.style.visibility = 'hidden';
  3297. if (!this.setFullScreenMode) {
  3298. this.cheditor.editArea.style.height = this.config.editorHeight;
  3299. }
  3300. this.cheditor.editArea.style.display = 'block';
  3301. this.cheditor.editArea.style.visibility = 'visible';
  3302. this.setDesignMode(true);
  3303. this.editAreaFocus();
  3304. if (outputHTML) {
  3305. startNode = this.doc.getElementById('startBogusNode');
  3306. endNode = this.doc.getElementById('endBogusNode');
  3307. if (startNode && endNode) {
  3308. scrollTop = 0;
  3309. pNode = startNode;
  3310. if (pNode) {
  3311. while (pNode.offsetParent) {
  3312. scrollTop += pNode.offsetTop;
  3313. pNode = pNode.offsetParent;
  3314. }
  3315. scrollTop -= this.getWindowSize(this.doc).height / 2;
  3316. }
  3317. if (this.doc.compatMode === 'CSS1Compat') {
  3318. this.doc.documentElement.scrollTop = scrollTop;
  3319. } else {
  3320. this.doc.body.scrollTop = scrollTop;
  3321. }
  3322. if (this.W3CRange) {
  3323. selection = this.clearSelection();
  3324. range = this.createRange();
  3325. range.setStartAfter(startNode);
  3326. range.setEndBefore(endNode);
  3327. try {
  3328. selection.addRange(range);
  3329. } catch (ignore) {
  3330. // display: none?
  3331. }
  3332. } else {
  3333. startRange = this.createRange();
  3334. endRange = startRange.duplicate();
  3335. startRange.moveToElementText(startNode);
  3336. endRange.moveToElementText(endNode);
  3337. startRange.setEndPoint('StartToEnd', startRange);
  3338. startRange.setEndPoint('EndToEnd', endRange);
  3339. startRange.select();
  3340. }
  3341. pNode = startNode.parentNode;
  3342. pNode.removeChild(startNode);
  3343. pNode = endNode.parentNode;
  3344. pNode.removeChild(endNode);
  3345. }
  3346. }
  3347. this.setImageEvent(true);
  3348. this.toolbarUpdate();
  3349. },
  3350. editMode: function () {
  3351. var self = this,
  3352. editorWidth, scrollBarWidth, scrollBarHeight, resize, content = null, borderWidth = 1, borderHeight = 1,
  3353. startPos, endPos, startNode, endNode, startEndNode,
  3354. editorHeight = this.cheditor.editWrapper.offsetHeight,
  3355. textContent = this.cheditor.textContent,
  3356. startNodeValue = 'startBogusNode', endNodeValue = 'endBogusNode',
  3357. startNodeCommentTag = '<!--' + startNodeValue + '-->', endNodeCommentTag = '<!--' + endNodeValue + '-->',
  3358. range = this.restoreRange();
  3359. if (this.cheditor.mode === 'preview') {
  3360. if (textContent.getAttribute('start-pos')) {
  3361. startPos = parseInt(textContent.getAttribute('start-pos'), 10);
  3362. textContent.removeAttribute('start-pos');
  3363. if (textContent.getAttribute('end-pos')) {
  3364. endPos = parseInt(textContent.getAttribute('end-pos'), 10);
  3365. textContent.removeAttribute('end-pos');
  3366. } else {
  3367. endPos = startPos;
  3368. }
  3369. content = textContent.value.replace(/\r\n/g, '\n');
  3370. } else {
  3371. this.placeCaretAt(this.doc.body.firstChild || this.doc.body, true);
  3372. range = this.getRange();
  3373. }
  3374. }
  3375. if (!content) {
  3376. startEndNode = this.insertStartEndNode(range);
  3377. startNode = this.doc.createComment(startNodeValue);
  3378. endNode = this.doc.createComment(endNodeValue);
  3379. startEndNode.startNode.parentNode.replaceChild(startNode, startEndNode.startNode);
  3380. startEndNode.endNode.parentNode.replaceChild(endNode, startEndNode.endNode);
  3381. startEndNode.startNode = startNode;
  3382. startEndNode.endNode = endNode;
  3383. content = this.getContents(startEndNode);
  3384. startPos = content.search(startNodeCommentTag);
  3385. endPos = content.search(endNodeCommentTag);
  3386. endPos -= endNodeCommentTag.length + 2;
  3387. content = content.replace(startNodeCommentTag, '').replace(endNodeCommentTag, '');
  3388. }
  3389. this.resetDocumentBody();
  3390. this.cheditor.editArea.style.display = 'none';
  3391. this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper-code';
  3392. this.cheditor.editBlock.style.display = 'none';
  3393. textContent.value = '';
  3394. textContent.style.lineHeight = '17px';
  3395. textContent.style.width = '100px';
  3396. textContent.style.height = '100px';
  3397. textContent.style.display = 'block';
  3398. scrollBarWidth = textContent.offsetWidth - 100;
  3399. scrollBarHeight = textContent.offsetHeight - 100;
  3400. if (this.browser.msie && this.browser.version < 8) {
  3401. scrollBarHeight += 2;
  3402. }
  3403. textContent.setAttribute('xbar-height', scrollBarHeight.toString());
  3404. textContent.setAttribute('ybar-width', scrollBarWidth.toString());
  3405. resize = textContent.offsetHeight + (editorHeight - textContent.offsetHeight) - scrollBarHeight - borderHeight;
  3406. textContent.style.height = resize + 'px';
  3407. this.resizeTextContent = function () {
  3408. editorWidth = self.cheditor.editWrapper.offsetWidth;
  3409. resize = textContent.offsetWidth + (editorWidth - textContent.offsetWidth) - scrollBarWidth - borderWidth;
  3410. self.cheditor.textContent.style.width = resize + 'px';
  3411. };
  3412. (function () {
  3413. self.addEvent(window, 'resize', self.resizeTextContent);
  3414. self.resizeTextContent();
  3415. })();
  3416. this.setTextContentSelection(startPos, endPos, content);
  3417. this.setDesignMode(false);
  3418. },
  3419. makeHtmlContent: function () {
  3420. var content = this.trimSpace(this.cheditor.textContent.value);
  3421. content = this.trimZeroSpace(content);
  3422. return content || '<p>&nbsp;</p>';
  3423. },
  3424. resetStatusBar: function () {
  3425. if (this.config.showTagPath) {
  3426. this.cheditor.tagPath.innerHTML = '&lt;html&gt; &lt;body&gt; ';
  3427. }
  3428. },
  3429. previewMode: function () {
  3430. var content, oSheet, pos = this.getTextContentSelectionPos(false);
  3431. if (this.cheditor.mode === 'code' && typeof this.resizeTextContent !== 'undefined') {
  3432. this.cheditor.textContent.setAttribute('start-pos', pos.startPos.toString());
  3433. this.cheditor.textContent.setAttribute('end-pos', pos.endPos.toString());
  3434. content = this.makeHtmlContent();
  3435. this.cheditor.textContent.blur();
  3436. this.cheditor.textContent.style.display = 'none';
  3437. this.removeEvent(window, 'resize', this.resizeTextContent);
  3438. this.putContents(content);
  3439. }
  3440. this.clearSelection();
  3441. this.cheditor.editBlock.style.display = 'none';
  3442. this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper-preview';
  3443. if (!this.setFullScreenMode) {
  3444. this.cheditor.editArea.style.height = this.config.editorHeight;
  3445. }
  3446. this.cheditor.editArea.style.display = 'block';
  3447. if (GB.browser.msie && parseInt(GB.browser.version, 10) === 8) {
  3448. try {
  3449. oSheet = this.doc.styleSheets[0];
  3450. oSheet.addRule('p:before', 'content:"\u200b"');
  3451. } catch (ignore) {
  3452. // ignore
  3453. }
  3454. }
  3455. this.setImageEvent(false);
  3456. this.setDesignMode(false);
  3457. },
  3458. convertContentsSpacer: function (content) {
  3459. var self = this, bogusBr = true,
  3460. excepted = '<span id="startBogusNode"><\/span><span id="endBogusNode"><\/span>',
  3461. reSpacer = new RegExp('<([^>]+)>(' + excepted + ')?(?:&nbsp;|\s+?|\u00a0)(' + excepted + ')?<\/([^>]+)>', 'g');
  3462. if (GB.browser.msie && GB.browser.msie_bogus === false) {
  3463. bogusBr = false;
  3464. }
  3465. content = content.replace(/\s{2,}|[\r\n\t]+?/gm, '');
  3466. content = content.replace(reSpacer,
  3467. function (all, open, excepted_a, excepted_b, close) {
  3468. var tagName = self.trimSpace(open.split(' ')[0]).toLowerCase(), rdata = null;
  3469. if (GB.lineHeightBlockTags[tagName] || GB.textFormatTags[tagName]) {
  3470. rdata = '<' + open + '>' + (excepted_a || '');
  3471. rdata += bogusBr ? '<br class="' + self.cheditor.bogusSpacerName + '" />' :
  3472. '<!--' + self.cheditor.bogusSpacerName + '-->';
  3473. rdata += (excepted_b || '') + '</' + close + '>';
  3474. }
  3475. return rdata || all;
  3476. }
  3477. );
  3478. return content;
  3479. },
  3480. putContents: function (content) {
  3481. if (this.config.fullHTMLSource) {
  3482. content = content.substr(content.search(/<html/ig) + 1);
  3483. content = content.substr(content.indexOf('>') + 1);
  3484. content = '<html>' + content;
  3485. this.doc.open();
  3486. this.doc.write('<body>' + content + '</body>');
  3487. this.doc.close();
  3488. } else {
  3489. content = '<span>remove_this</span>' + content;
  3490. this.doc.body.innerHTML = content;
  3491. this.doc.body.removeChild(this.doc.body.firstChild);
  3492. }
  3493. },
  3494. getImages: function () {
  3495. var img = this.doc.body.getElementsByTagName('img'),
  3496. imgLength = this.images.length,
  3497. imgs = [], i, imgId, j;
  3498. for (i = 0; i < img.length; i++) {
  3499. if (img[i].src) {
  3500. imgId = img[i].src;
  3501. imgId = imgId.slice(imgId.lastIndexOf('/') + 1);
  3502. for (j = 0; j < imgLength; j++) {
  3503. if (this.images[j].fileName === imgId) {
  3504. imgs.push(this.images[j]);
  3505. break;
  3506. }
  3507. }
  3508. }
  3509. }
  3510. return imgs.length > 0 ? imgs : null;
  3511. },
  3512. getElementStyle: function (elem) {
  3513. return (window.getComputedStyle) ? this.doc.defaultView.getComputedStyle(elem, null) : elem.currentStyle;
  3514. },
  3515. getElementDefaultDisplay: function (elem) {
  3516. return (window.getComputedStyle ? this.doc.defaultView.getComputedStyle(elem, null) : elem.currentStyle).display;
  3517. },
  3518. tabRepeat: function (count) {
  3519. var i = 0, tab = '';
  3520. if (count < 1) {
  3521. return tab;
  3522. }
  3523. for (; i < count; i++) {
  3524. tab += this.cheditor.tabSpaces;
  3525. }
  3526. return tab;
  3527. },
  3528. htmlEncode: function (text) {
  3529. //text = text.replace(/\n{2,}$/g, '\n');
  3530. //text = text.replace(/&/g, '&amp;');
  3531. text = text.replace(/</g, '&lt;');
  3532. text = text.replace(/>/g, '&gt;');
  3533. text = text.replace(/\u00a0/g, '&nbsp;');
  3534. //text = text.replace(/<font ([^>]+)>&nbsp;<\/font>/mgi, '');
  3535. //text = text.replace(/\x22/g, '&quot;');
  3536. return text;
  3537. },
  3538. checkDocLinks: function () {
  3539. var links = this.doc.links,
  3540. len = links.length,
  3541. host = location.host,
  3542. i, href;
  3543. this.cheditor.links = [];
  3544. for (i = 0; i < len; i++) {
  3545. if (!this.config.includeHostname) {
  3546. href = links[i].href;
  3547. if (href.indexOf(host) !== -1) {
  3548. links[i].setAttribute('href', href.substring(href.indexOf(host) + host.length));
  3549. }
  3550. }
  3551. if (this.config.linkTarget !== '' && this.config.linkTarget !== null) {
  3552. if (!(links[i].getAttribute('target'))) {
  3553. links[i].setAttribute('target', this.config.linkTarget);
  3554. }
  3555. }
  3556. if (GB.browser.msie) {
  3557. this.cheditor.links.push(links[i]);
  3558. }
  3559. }
  3560. },
  3561. checkDocImages: function () {
  3562. var img = this.doc.images,
  3563. len = img.length,
  3564. host = location.host,
  3565. i = 0, imgUrl;
  3566. for (; i < len; i++) {
  3567. if (!this.config.includeHostname) {
  3568. imgUrl = img[i].src;
  3569. if (imgUrl) {
  3570. if (imgUrl.indexOf(host) !== -1) {
  3571. img[i].src = imgUrl.substring(imgUrl.indexOf(host) + host.length);
  3572. }
  3573. }
  3574. }
  3575. if (img[i].style.width) {
  3576. img[i].removeAttribute('width');
  3577. }
  3578. if (img[i].style.height) {
  3579. img[i].removeAttribute('height');
  3580. }
  3581. }
  3582. },
  3583. createNbspTextNode: function () {
  3584. return this.doc.createTextNode('\u00a0');
  3585. },
  3586. getNodeTree: function (pNode, callback) {
  3587. function Node(node) {
  3588. this.node = node;
  3589. this.name = node.nodeName.toLowerCase();
  3590. this.type = node.nodeType;
  3591. this.parent = node.parentNode;
  3592. this.indent = 0;
  3593. }
  3594. (function recurse(cNode, indent) {
  3595. var i, child,
  3596. node = new Node(cNode),
  3597. children = cNode.childNodes,
  3598. len = children.length;
  3599. node.indent = indent;
  3600. for (i = 0; i < len; i++) {
  3601. child = children[i];
  3602. if (child) {
  3603. recurse(child, indent + 1);
  3604. }
  3605. }
  3606. if (node.name !== 'body') {
  3607. callback(node);
  3608. }
  3609. })(pNode, -1);
  3610. },
  3611. getContents: function (startEndNode) {
  3612. var self = this,
  3613. mydoc, indentNodes = [], i, node, msie_c = typeof this.browser.msie_c !== 'undefined',
  3614. allowedIndent = this.getContents.caller !== this.getBodyContents,
  3615. insertTabSpace = function (indent) {
  3616. return msie_c ? self.doc.createComment('Tab Size:' + indent) :
  3617. self.doc.createTextNode('\n' + self.tabRepeat(indent));
  3618. };
  3619. function checkChildNodes(child) {
  3620. if (!child) {
  3621. return null;
  3622. }
  3623. if (!startEndNode) {
  3624. return child;
  3625. }
  3626. do {
  3627. if (child !== startEndNode.startNode && child !== startEndNode.endNode) {
  3628. break;
  3629. }
  3630. child = child.nextSibling;
  3631. } while (child);
  3632. return child;
  3633. }
  3634. this.checkDocLinks();
  3635. this.checkDocImages();
  3636. this.getNodeTree(this.doc.body, function (node) {
  3637. if (!node.node) {
  3638. return;
  3639. }
  3640. if (self.config.exceptedElements[node.name]) {
  3641. node.parent.replaceChild(self.doc.createTextNode(''), node.node);
  3642. return;
  3643. }
  3644. switch (node.type) {
  3645. case GB.node.text:
  3646. if (!self.isTextVisible(node.node.nodeValue)) {
  3647. node.parent.replaceChild(self.doc.createTextNode(''), node.node);
  3648. }
  3649. break;
  3650. case GB.node.element:
  3651. if (node.node.className === self.cheditor.bogusSpacerName) {
  3652. if (node.node.firstChild === null) {
  3653. if (node.name === 'br') {
  3654. node.parent.removeChild(node.node);
  3655. if (!checkChildNodes(node.parent.firstChild)) {
  3656. node.parent.appendChild(self.createNbspTextNode());
  3657. }
  3658. } else {
  3659. node.node.appendChild(self.createNbspTextNode());
  3660. }
  3661. } else if (!checkChildNodes(node.node.firstChild)) {
  3662. node.node.appendChild(self.createNbspTextNode());
  3663. }
  3664. node.node.className = '';
  3665. }
  3666. if ((node.name === 'p' || node.name === 'div') && !checkChildNodes(node.node.firstChild)) {
  3667. node.node.appendChild(self.createNbspTextNode());
  3668. }
  3669. if (GB.newLineBeforeTags[node.name] && allowedIndent) {
  3670. if (node.node.firstChild && (node.node.firstChild.nodeType === GB.node.element)) {
  3671. node.node.insertBefore(insertTabSpace(node.indent + 1), node.node.firstChild);
  3672. node.node.appendChild(insertTabSpace(node.indent));
  3673. }
  3674. indentNodes.push(node);
  3675. }
  3676. if (GB.selfClosingTags[node.name]) {
  3677. node.node.setAttribute('self-close-tag', '1');
  3678. }
  3679. break;
  3680. case GB.node.comment:
  3681. if (node.node.nodeValue === self.cheditor.bogusSpacerName) {
  3682. node.parent.removeChild(node.node);
  3683. if (!checkChildNodes(node.parent.firstChild)) {
  3684. node.parent.appendChild(self.createNbspTextNode());
  3685. } else if (node.parent.firstChild.nodeName.toLowerCase() === 'br') {
  3686. node.parent.replaceChild(self.createNbspTextNode(), node.node.firstChild);
  3687. }
  3688. }
  3689. }
  3690. });
  3691. for (i in indentNodes) {
  3692. if (indentNodes.hasOwnProperty(i)) {
  3693. node = indentNodes[i];
  3694. node.parent.insertBefore(insertTabSpace(node.indent), node.node);
  3695. if (node.node.nextSibling) {
  3696. node.node.nextSibling.parentNode.insertBefore(insertTabSpace(node.indent), node.node.nextSibling);
  3697. } else {
  3698. node.parent.appendChild(insertTabSpace(node.indent));
  3699. }
  3700. }
  3701. }
  3702. indentNodes = [];
  3703. mydoc = this.doc.body.innerHTML;
  3704. mydoc = mydoc.replace(/^\s*[\r\n]/gm, '').replace(/\u200b/g, '');
  3705. if (msie_c) {
  3706. mydoc = mydoc.replace(/<!--Tab Size:(\d+)-->(?:[\r\n]*)/g,
  3707. function (a, b) {
  3708. return '\n' + self.tabRepeat(b);
  3709. }).replace(/<(\/?)([A-Za-z]+)([^>]*)>/g,
  3710. function (a, close, tag, attr) {
  3711. attr = attr.replace(/\s(\w+)=([^'"\s>]+)/g,
  3712. function (a, k, v) {
  3713. return ' ' + k.toLowerCase() + '="' + v + '"';
  3714. }).replace(/([A-Za-z\-]+)(?:\s*):\s+?/g,
  3715. function (a, k) {
  3716. return k.toLowerCase() + ': ';
  3717. });
  3718. return '<' + close + tag.toLowerCase() + attr + '>';
  3719. }
  3720. );
  3721. }
  3722. mydoc = mydoc.replace(/<[^>]+>/gm, function (match) {
  3723. match = match.replace(/\sself-close-tag="1"([^>]+)?/g, '$1 /');
  3724. if (self.config.allowedOnEvent !== true) {
  3725. match = match.replace(/\s+on([A-Za-z]+)=("[^"]*"|'[^']*'|[^\s>]*)/g, '');
  3726. }
  3727. if (self.config.colorToHex) {
  3728. match = match.replace(/(background-color|color)\s*([:=])\s*(rgba?)\(\s*(\d+)\s*,\s*(\d+),\s*(\d+)\)/ig,
  3729. function (all, p, s, rgb, r, g, b) {
  3730. return p + s + ' ' + self.colorConvert(rgb + '(' + r + ',' + g + ',' + b + ')', 'hex');
  3731. });
  3732. } else {
  3733. match = match.replace(/(background-color|color)\s*([:=])\s*(#[A-Fa-f0-9]{3,6})/ig,
  3734. function (all, p, s, hex) {
  3735. return p + s + ' ' + self.colorConvert(hex, 'rgb');
  3736. });
  3737. }
  3738. return match;
  3739. });
  3740. return mydoc;
  3741. },
  3742. returnContents: function (mydoc) {
  3743. mydoc = this.removeEmptyBogusTag(mydoc);
  3744. this.setDesignMode(true);
  3745. this.cheditor.textarea.value = mydoc;
  3746. return mydoc;
  3747. },
  3748. makeAmpTag: function (str) {
  3749. return str.replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g, '&amp;gt;');
  3750. },
  3751. removeAmpTag: function (str) {
  3752. if (this.config.removeIndent) {
  3753. str = str.replace(/^[\t]+/gm, '');
  3754. }
  3755. return str.replace(/&amp;lt;/g, '&lt;').replace(/&amp;gt;/g, '&gt;');
  3756. },
  3757. getOutputContents: function () {
  3758. this.resetViewHTML();
  3759. return this.removeAmpTag(this.getContents(null));
  3760. },
  3761. outputHTML: function () {
  3762. return '<!DOCTYPE html>\n' +
  3763. '<html>\n' +
  3764. ' <head>\n' +
  3765. ' <title>' + this.config.docTitle + '</title>\n' +
  3766. ' </head>\n' +
  3767. ' <body>\n' +
  3768. this.returnContents(this.getOutputContents()) +
  3769. ' </body>\n' +
  3770. '</html>';
  3771. },
  3772. getBodyContents: function () {
  3773. return (this.cheditor.mode === 'code') ? this.makeHtmlContent() : this.getContents(null);
  3774. },
  3775. outputBodyHTML: function () {
  3776. return this.returnContents(this.getOutputContents());
  3777. },
  3778. outputBodyText: function () {
  3779. return this.returnContents(this.getBodyText());
  3780. },
  3781. getBodyText: function () {
  3782. this.resetViewHTML();
  3783. return this.trimSpace(String(GB.browser.msie ? this.doc.body.innerText : this.doc.body.textContent));
  3784. },
  3785. returnFalse: function () {
  3786. var img = this.doc.images, i;
  3787. this.editAreaFocus();
  3788. for (i = 0; i < img.length; i++) {
  3789. if (img[i].src) {
  3790. if (img[i].getAttribute('onload')) {
  3791. img[i].onload = 'true';
  3792. }
  3793. } else {
  3794. img[i].removeAttribute('onload');
  3795. img[i].removeAttribute('className');
  3796. }
  3797. }
  3798. return false;
  3799. },
  3800. trimZeroSpace: function (str) {
  3801. return str ? str.replace(/[\ufeff\u200b\xa0\u3000]+/gm, '') : '';
  3802. },
  3803. trimSpace: function (str) {
  3804. return str ? str.replace(/^[\s\ufeff\u200b\xa0\u3000]+|[\s\ufeff\u200b\xa0\u3000]+$/g, '') : '';
  3805. },
  3806. makeRandomString: function () {
  3807. var chars = '_-$@!#0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz',
  3808. len = 32,
  3809. clen = chars.length,
  3810. rData = '', i, rnum;
  3811. for (i = 0; i < len; i++) {
  3812. rnum = Math.floor(Math.random() * clen);
  3813. rData += chars.substring(rnum, rnum + 1);
  3814. }
  3815. return rData;
  3816. },
  3817. strLength: function (str) {
  3818. var len = str.length, mbytes = 0, i, c;
  3819. for (i = 0; i < len; i++) {
  3820. c = str.charCodeAt(i);
  3821. if (c > 128) {
  3822. mbytes++;
  3823. }
  3824. }
  3825. return (len - mbytes) + (mbytes * 2);
  3826. },
  3827. resetViewHTML: function () {
  3828. if (this.cheditor.mode === 'code') {
  3829. this.switchEditorMode('rich');
  3830. }
  3831. },
  3832. contentsLengthAll: function () {
  3833. return this.strLength(this.outputHTML());
  3834. },
  3835. contentsLength: function () {
  3836. var content = String(this.trimSpace(this.outputBodyHTML()));
  3837. if (!content) {
  3838. return 0;
  3839. }
  3840. return this.strLength(content);
  3841. },
  3842. inputLength: function () {
  3843. var content = this.getBodyText();
  3844. if (content === '') {
  3845. return 0;
  3846. }
  3847. return this.strLength(content);
  3848. },
  3849. displayWindow: function (pNode, id) {
  3850. var pullDown = this.pulldown[id];
  3851. this.editAreaFocus();
  3852. this.backupRange();
  3853. this.boxHideAll(id);
  3854. pullDown.style.visibility = 'visible';
  3855. pullDown.style.zIndex = 10002;
  3856. pullDown.focus();
  3857. },
  3858. pulldownMouseOver: function (el) {
  3859. if (el.className === 'cheditor-pulldown-selected') {
  3860. return;
  3861. }
  3862. el.className = 'cheditor-pulldown-mouseover';
  3863. },
  3864. pulldownMouseOut: function (el) {
  3865. if (el.className === 'cheditor-pulldown-selected') {
  3866. return;
  3867. }
  3868. el.className = 'cheditor-pulldown-mouseout';
  3869. },
  3870. windowPos: function (pNode, id) {
  3871. var left = pNode.offsetLeft, box = this.pulldown[id];
  3872. if (this.toolbar[id].type === 'combobox') {
  3873. left -= parseInt(this.toolbar[this.toolbar[id].node].width, 10);
  3874. }
  3875. if (this.toolbar[id].prev && !this.toolbar[id].next) {
  3876. left -= 1;
  3877. }
  3878. box.style.left = left + 'px';
  3879. box.style.top = pNode.offsetTop + parseInt(pNode.style.height, 10) + 'px';
  3880. },
  3881. boxHideAll: function (showId) {
  3882. var menu, box, ishide;
  3883. for (menu in this.pulldown) {
  3884. if (this.pulldown.hasOwnProperty(menu)) {
  3885. box = this.pulldown[menu];
  3886. if (box) {
  3887. box.style.visibility = 'hidden';
  3888. ishide = this.undefined(showId) ? true : (menu !== showId);
  3889. if (ishide && this.toolbar[menu].checked) {
  3890. this.toolbar[menu].checked = false;
  3891. this.toolbarButtonUnchecked(this.toolbar[menu]);
  3892. }
  3893. }
  3894. }
  3895. }
  3896. this.editAreaFocus();
  3897. },
  3898. createWindow: function (width, elem) {
  3899. elem.className = 'cheditor-pulldown-container';
  3900. elem.style.width = width + 'px';
  3901. },
  3902. setColorTable: function (menu) {
  3903. var self = this,
  3904. pulldown = document.createElement('div'),
  3905. len = GB.colors.length,
  3906. container = document.createElement('div'),
  3907. selected = document.createElement('input'),
  3908. selectedValue = document.createElement('input'),
  3909. cellWrapper = document.createElement('div'),
  3910. br = document.createElement('div'),
  3911. reset = document.createElement('span'),
  3912. pickerSwitch = document.createElement('span'),
  3913. button = document.createElement('img'),
  3914. showTooltip = '더 많은 색 보기',
  3915. hideTooltip = '감추기',
  3916. i, cell, color = 0, colorPicker, cellBorder,
  3917. onMouseOverEventHandler = function () {
  3918. colorPicker.fromString(this.id);
  3919. this.parentNode.className = 'cheditor-pulldown-color-cell-over';
  3920. },
  3921. onMouseOutEventHandler = function () {
  3922. this.parentNode.className = 'cheditor-pulldown-color-cell';
  3923. },
  3924. onClickEventHandler = function () {
  3925. self.doCmdPopup(menu, this.id);
  3926. },
  3927. onResetEventHandler = function () {
  3928. colorPicker.fromString(self.colorConvert(selectedValue.style.backgroundColor, 'hex'));
  3929. },
  3930. onPickerEventHandler = function () {
  3931. if (self.toolbar[menu].colorNode.showPicker) {
  3932. colorPicker.hidePicker();
  3933. self.toolbar[menu].colorNode.showPicker = false;
  3934. pickerSwitch.setAttribute('title', showTooltip);
  3935. } else {
  3936. colorPicker.showPicker();
  3937. self.toolbar[menu].colorNode.showPicker = true;
  3938. pickerSwitch.setAttribute('title', hideTooltip);
  3939. }
  3940. },
  3941. onSubmitEventHandler = function () {
  3942. self.doCmdPopup(menu, selected.value);
  3943. };
  3944. selected.setAttribute('type', 'text');
  3945. selected.setAttribute('maxlength', '7');
  3946. selected.className = 'cheditor-pulldown-color-selected';
  3947. selectedValue.setAttribute('type', 'text');
  3948. selectedValue.onfocus = function () {
  3949. selected.focus();
  3950. };
  3951. selectedValue.style.cursor = 'default';
  3952. selectedValue.className = 'cheditor-pulldown-color-selected';
  3953. selected.style.marginLeft = '-1px';
  3954. selected.style.borderLeft = 'none';
  3955. selected.spellcheck = false;
  3956. cellWrapper.style.margin = '2px';
  3957. cellWrapper.style.position = 'relative';
  3958. container.style.position = 'relative';
  3959. br.style.clear = 'both';
  3960. br.style.height = '0px';
  3961. colorPicker = new GB.colorDropper(selected, { 'iconDir': this.config.iconPath });
  3962. for (i = 0; i < len; i++) {
  3963. if (i % 13 === 0) {
  3964. cellWrapper.appendChild(br.cloneNode(true));
  3965. if (i === 26) {
  3966. cellWrapper.lastChild.style.height = '4px';
  3967. }
  3968. len++;
  3969. continue;
  3970. }
  3971. cellBorder = document.createElement('span');
  3972. cellBorder.className = 'cheditor-pulldown-color-cell';
  3973. cell = document.createElement('span');
  3974. cell.id = GB.colors[color];
  3975. cell.style.backgroundColor = GB.colors[color++];
  3976. cell.appendChild(document.createTextNode('\u00a0'));
  3977. cellBorder.appendChild(cell);
  3978. cellWrapper.appendChild(cellBorder);
  3979. (function () {
  3980. cell.onclick = onClickEventHandler;
  3981. cell.onmouseover = onMouseOverEventHandler;
  3982. cell.onmouseout = onMouseOutEventHandler;
  3983. })();
  3984. }
  3985. cellWrapper.appendChild(br);
  3986. cellWrapper.appendChild(selectedValue);
  3987. cellWrapper.appendChild(selected);
  3988. reset.appendChild(document.createTextNode('\u00a0'));
  3989. reset.className = 'cheditor-pulldown-color-reset';
  3990. reset.onclick = onResetEventHandler;
  3991. cellWrapper.appendChild(reset);
  3992. pickerSwitch.appendChild(document.createTextNode('\u00a0'));
  3993. pickerSwitch.className = 'cheditor-pulldown-color-show-picker';
  3994. pickerSwitch.setAttribute('title', showTooltip);
  3995. pickerSwitch.onclick = onPickerEventHandler;
  3996. cellWrapper.appendChild(pickerSwitch);
  3997. button.className = 'cheditor-pulldown-color-submit';
  3998. button.src = this.config.iconPath + 'button/input_color.gif';
  3999. button.onclick = onSubmitEventHandler;
  4000. cellWrapper.appendChild(button);
  4001. container.appendChild(cellWrapper);
  4002. self.toolbar[menu].colorNode.selectedValue = selectedValue;
  4003. self.toolbar[menu].colorNode.colorPicker = colorPicker;
  4004. pulldown.appendChild(container);
  4005. return pulldown;
  4006. },
  4007. onKeyPressToolbarUpdate: function () {
  4008. var self = this;
  4009. if (this.tempTimer) {
  4010. clearTimeout(this.tempTimer);
  4011. }
  4012. this.tempTimer = setTimeout(function () {
  4013. if (self.config.showTagPath) {
  4014. self.doEditorEvent();
  4015. } else {
  4016. self.toolbarUpdate();
  4017. }
  4018. self.tempTimer = null;
  4019. }, 50);
  4020. },
  4021. doOnKeyDown: function (evt) {
  4022. switch (evt.keyCode) {
  4023. case 37: case 38: case 39: case 40: case 46: case 8:
  4024. this.onKeyPressToolbarUpdate(evt);
  4025. }
  4026. },
  4027. doOnKeyUp: function (evt) {
  4028. var caretRange, css, enterNode, i, keyCode = evt.keyCode, node, self = this, storedNode, storedRange,
  4029. clearBackgroundColor = function (cNode) {
  4030. if (cNode.nodeType !== GB.node.element || cNode.hasChildNodes() || !cNode.getAttribute('style')) {
  4031. return cNode;
  4032. }
  4033. if (GB.textFormatTags[cNode.nodeName.toLowerCase()]) {
  4034. css = self.checkCssValue(cNode, 'background-color');
  4035. if (css) {
  4036. css = self.clearCss(cNode, 'background-color');
  4037. if (cNode.nodeName.toLowerCase() === 'span' && !css) {
  4038. node = cNode.parentNode;
  4039. node.removeChild(cNode);
  4040. return node;
  4041. }
  4042. }
  4043. }
  4044. return cNode;
  4045. };
  4046. if (keyCode !== 13 || this.cheditor.mode !== 'rich') {
  4047. return;
  4048. }
  4049. if (typeof GB.browser.msie_c !== 'undefined') {
  4050. node = this.storedSelections[0];
  4051. if (!node) {
  4052. return;
  4053. }
  4054. if (node.className === this.cheditor.bogusSpacerName) {
  4055. node.className = '';
  4056. }
  4057. while (node.firstChild) {
  4058. node = node.firstChild;
  4059. }
  4060. if (node.nodeType === GB.node.element && node.canHaveChildren) {
  4061. node.className = this.cheditor.bogusSpacerName;
  4062. }
  4063. return;
  4064. }
  4065. caretRange = this.getRange();
  4066. enterNode = caretRange.commonAncestorContainer;
  4067. if (GB.browser.msie || GB.browser.edge) {
  4068. this.backupRange(caretRange);
  4069. if (enterNode.nodeType === GB.node.element) {
  4070. enterNode = clearBackgroundColor(enterNode);
  4071. enterNode.className = this.cheditor.bogusSpacerName;
  4072. }
  4073. for (i = 0; i < this.keyPressStoredSelections.length; i++) {
  4074. storedRange = this.keyPressStoredSelections[i];
  4075. storedNode = storedRange.commonAncestorContainer;
  4076. if (storedNode && storedNode.nodeType === GB.node.element) {
  4077. node = storedNode.childNodes[storedRange.startOffset];
  4078. if (!node) {
  4079. break;
  4080. }
  4081. while (node.firstChild) {
  4082. node = node.firstChild;
  4083. }
  4084. node = clearBackgroundColor(node);
  4085. node.className = this.cheditor.bogusSpacerName;
  4086. }
  4087. }
  4088. this.restoreRange();
  4089. this.keyPressStoredSelections = [];
  4090. } else {
  4091. this.applyBogusClassName(caretRange);
  4092. }
  4093. },
  4094. doOnKeyPress: function (evt) {
  4095. var keyCode = evt.keyCode, caretRange;
  4096. if (keyCode && keyCode === 13 && this.cheditor.mode === 'rich') {
  4097. caretRange = this.getRange();
  4098. if (typeof this.browser.msie_c !== 'undefined') {
  4099. try {
  4100. this.storedSelections[0] = caretRange.parentElement();
  4101. } catch (e) {
  4102. this.keyPressBackupRange();
  4103. }
  4104. } else if (GB.browser.msie || GB.browser.edge) {
  4105. this.keyPressBackupRange();
  4106. } else {
  4107. this.applyBogusClassName(caretRange);
  4108. }
  4109. }
  4110. },
  4111. applyBogusClassName: function (range) {
  4112. var node = range.commonAncestorContainer;
  4113. if (range.startOffset < 1 && (!node.lastChild || node.lastChild.nodeName.toLowerCase() !== 'br')) {
  4114. do {
  4115. if (node.parentNode.nodeName.toLowerCase() === 'body') {
  4116. break;
  4117. }
  4118. node = node.parentNode;
  4119. } while (GB.textFormatTags[node.nodeName.toLowerCase()]);
  4120. node = node.previousSibling;
  4121. if (node) {
  4122. while (node.firstChild) {
  4123. node = node.firstChild;
  4124. }
  4125. if (node.nodeType === GB.node.element && node.nodeName.toLowerCase() === 'br') {
  4126. node.className = this.cheditor.bogusSpacerName;
  4127. }
  4128. }
  4129. } else {
  4130. if (!node || node.nodeType !== GB.node.element) {
  4131. return;
  4132. }
  4133. if (node.lastChild
  4134. && node.lastChild.nodeName.toLowerCase() === 'br'
  4135. && node.lastChild.className !== this.cheditor.bogusSpacerName) {
  4136. node.lastChild.className = this.cheditor.bogusSpacerName;
  4137. }
  4138. }
  4139. },
  4140. setWinPosition: function (oWin, popupAttr, windowSize) {
  4141. oWin.style.width = popupAttr.width + 'px';
  4142. oWin.style.left = Math.round(((this.cheditor.editArea.clientWidth - popupAttr.width) / 2) +
  4143. windowSize.offsetLeft) + 'px';
  4144. oWin.style.top = Math.round(windowSize.offsetTop) + 'px';
  4145. },
  4146. getWindowSize: function (doc) {
  4147. var mydoc = doc || document,
  4148. docMode = mydoc.compatMode === 'CSS1Compat',
  4149. docBody = mydoc.body,
  4150. docElem = mydoc.documentElement,
  4151. factor, rect, physicalWidth, logicalWidth,
  4152. editAreaRect,
  4153. rData = {
  4154. width: docMode ? docElem.clientWidth : docBody.clientWidth,
  4155. height: docMode ? docElem.clientHeight : docBody.clientHeight,
  4156. scrollHeight: docMode ? docElem.scrollHeight : docBody.scrollHeight,
  4157. scrollWidth: docMode ? docElem.scrollWidth : docBody.scrollWidth
  4158. };
  4159. if (this.undefined(window.pageXOffset)) {
  4160. factor = 1;
  4161. if (docBody.getBoundingClientRect) {
  4162. rect = docBody.getBoundingClientRect();
  4163. physicalWidth = rect.right - rect.left;
  4164. logicalWidth = mydoc.body.offsetWidth;
  4165. factor = Math.round((physicalWidth / logicalWidth) * 100) / 100;
  4166. }
  4167. rData.scrollY = Math.round(docElem.scrollTop / factor);
  4168. rData.scrollX = Math.round(docElem.scrollLeft / factor);
  4169. } else {
  4170. rData.scrollY = window.pageYOffset;
  4171. rData.scrollX = window.pageXOffset;
  4172. }
  4173. editAreaRect = this.cheditor.editArea.getBoundingClientRect();
  4174. rData.clientTop = docElem.clientTop || docBody.clientTop || 0;
  4175. rData.clientLeft = docElem.clientLeft || docBody.clientLeft || 0;
  4176. rData.offsetTop = rData.scrollY + (rData.height / 2);
  4177. rData.offsetLeft = editAreaRect.left + rData.scrollX - rData.clientLeft;
  4178. return rData;
  4179. },
  4180. popupWinLoad: function (popupAttr) {
  4181. var self = this,
  4182. windowSize = self.getWindowSize(),
  4183. iframe = document.createElement('iframe'),
  4184. body = document.getElementsByTagName('body')[0],
  4185. done = false,
  4186. popWinResizeHeight = function (evt) {
  4187. iframe.contentWindow.focus();
  4188. iframe.contentWindow.init.call(self, iframe, popupAttr.argv || null);
  4189. if (self.cheditor.popupElem.style.visibility !== 'visible') {
  4190. self.cheditor.popupElem.style.top = Math.ceil(parseInt(self.cheditor.popupElem.style.top, 10) -
  4191. Math.ceil(self.cheditor.popupElem.clientHeight / 2)) + 'px';
  4192. self.cheditor.popupElem.style.visibility = 'visible';
  4193. }
  4194. self.stopEvent(evt);
  4195. },
  4196. modalResize = function () {
  4197. self.cheditor.modalBackground.style.height = (windowSize.scrollHeight > windowSize.height) ?
  4198. windowSize.scrollHeight : windowSize.height + 'px';
  4199. if (window.scrollWidth > window.width) {
  4200. self.cheditor.modalBackground.style.width = windowSize.width +
  4201. (windowSize.scrollWidth - windowSize.width) + 'px';
  4202. } else {
  4203. self.cheditor.modalBackground.style.width = windowSize.width + 'px';
  4204. }
  4205. self.cheditor.modalBackground.style.left = windowSize.scrollX + 'px';
  4206. },
  4207. onReadyStateChangeEventHandler = function (evt) {
  4208. if (!done && (!this.readyState || this.readyState === 'complete' || this.readyState === 'loaded')) {
  4209. popWinResizeHeight(evt);
  4210. done = true;
  4211. }
  4212. };
  4213. if (self.cheditor.popupTitle.hasChildNodes()) {
  4214. self.cheditor.popupTitle.removeChild(self.cheditor.popupTitle.firstChild);
  4215. }
  4216. if (self.cheditor.popupFrameWrapper.hasChildNodes()) {
  4217. self.cheditor.popupFrameWrapper.removeChild(self.cheditor.popupFrameWrapper.firstChild);
  4218. }
  4219. self.cheditor.popupTitle.appendChild(document.createTextNode(popupAttr.title));
  4220. self.cheditor.popupElem.style.zIndex = self.modalElementZIndex + 100;
  4221. self.setWinPosition(self.cheditor.popupElem, popupAttr, windowSize);
  4222. iframe.setAttribute('frameBorder', '0');
  4223. iframe.setAttribute('height', '0');
  4224. iframe.setAttribute('width', String(popupAttr.width - 22));
  4225. iframe.setAttribute('name', popupAttr.tmpl);
  4226. iframe.setAttribute('src', self.config.popupPath + popupAttr.tmpl);
  4227. iframe.id = popupAttr.tmpl;
  4228. self.cheditor.modalBackground.style.zIndex = self.modalElementZIndex;
  4229. body.insertBefore(self.cheditor.modalBackground, body.firstChild);
  4230. body.insertBefore(self.cheditor.popupElem, body.firstChild);
  4231. self.cheditor.popupFrameWrapper.appendChild(iframe);
  4232. self.cheditor.popupElem.style.visibility = 'hidden';
  4233. self.cheditor.popupElem.style.display = 'block';
  4234. self.cheditor.modalBackground.style.display = 'block';
  4235. GB.dragWindow.init(self.cheditor.dragHandle, self.cheditor.popupElem);
  4236. (function () {
  4237. if (GB.browser.msie && !(self.undefined(iframe.onreadystatechange))) {
  4238. iframe.onreadystatechange = onReadyStateChangeEventHandler;
  4239. } else {
  4240. iframe.onload = popWinResizeHeight;
  4241. }
  4242. if (GB.browser.msie && GB.browser.version < 9) {
  4243. window.onresize = function () {
  4244. windowSize = self.getWindowSize();
  4245. modalResize();
  4246. };
  4247. modalResize();
  4248. self.cheditor.modalBackground.style.filter = 'alpha(opacity=50)';
  4249. self.cheditor.modalBackground.style.opacity = 0.5;
  4250. } else {
  4251. self.cheditor.modalBackground.style.opacity = 0.5;
  4252. }
  4253. self.cheditor.modalBackground.focus();
  4254. })();
  4255. },
  4256. popupWinCancel: function () {
  4257. this.restoreRange();
  4258. this.popupWinClose();
  4259. },
  4260. popupWinClose: function () {
  4261. if (!this.cheditor.popupElem) {
  4262. return;
  4263. }
  4264. this.cheditor.popupElem.style.display = 'none';
  4265. this.cheditor.popupElem.style.zIndex = -1;
  4266. this.cheditor.popupFrameWrapper.src = '';
  4267. if (this.cheditor.popupFrameWrapper.hasChildNodes()) {
  4268. this.cheditor.popupFrameWrapper.removeChild(this.cheditor.popupFrameWrapper.firstChild);
  4269. }
  4270. this.cheditor.modalBackground.style.display = 'none';
  4271. this.cheditor.modalBackground.style.zIndex = -1;
  4272. if (this.modalReSize !== null) {
  4273. if (GB.browser.opera) {
  4274. window.removeEventListener('resize', this.modaReSize, false);
  4275. }
  4276. this.modalReSize = null;
  4277. }
  4278. this.editAreaFocus();
  4279. },
  4280. clearStoredSelections: function () {
  4281. this.storedSelections.splice(0, this.storedSelections.length);
  4282. },
  4283. restoreRange: function () {
  4284. var range = null, selection = null;
  4285. if (this.storedSelections[0]) {
  4286. if (this.W3CRange) {
  4287. selection = this.getSelection();
  4288. if (selection.rangeCount > 0) {
  4289. selection.removeAllRanges();
  4290. }
  4291. selection.addRange(this.storedSelections[0]);
  4292. range = selection.getRangeAt(0);
  4293. } else {
  4294. range = this.createRange();
  4295. if (this.storedSelections[0]) {
  4296. if (typeof this.storedSelections[0] === 'string') {
  4297. range.moveToBookmark(this.storedSelections[0]);
  4298. } else {
  4299. range = this.storedSelections[0];
  4300. }
  4301. }
  4302. range.select();
  4303. }
  4304. }
  4305. return range;
  4306. },
  4307. keyPressBackupRange: function (range) {
  4308. var selection = null, i;
  4309. if (this.W3CRange) {
  4310. selection = this.getSelection();
  4311. if (selection) {
  4312. for (i = 0; i < selection.rangeCount; i++) {
  4313. this.keyPressStoredSelections.push(selection.getRangeAt(i));
  4314. }
  4315. }
  4316. } else {
  4317. range = range || this.getRange();
  4318. switch (this.getSelectionType()) {
  4319. case GB.selection.none:
  4320. case GB.selection.text:
  4321. this.storedSelections[0] = range.getBookmark();
  4322. break;
  4323. case GB.selection.element:
  4324. this.storedSelections[0] = range;
  4325. break;
  4326. default:
  4327. this.storedSelections[0] = null;
  4328. }
  4329. }
  4330. },
  4331. backupRange: function (range) {
  4332. var selection = null;
  4333. if (this.W3CRange) {
  4334. selection = this.getSelection();
  4335. if (selection && selection.rangeCount > 0) {
  4336. this.storedSelections[0] = selection.getRangeAt(0);
  4337. }
  4338. } else {
  4339. range = range || this.getRange();
  4340. switch (this.getSelectionType()) {
  4341. case GB.selection.none:
  4342. case GB.selection.text:
  4343. this.storedSelections[0] = range.getBookmark();
  4344. break;
  4345. case GB.selection.element:
  4346. this.storedSelections[0] = range;
  4347. break;
  4348. default:
  4349. this.storedSelections[0] = null;
  4350. }
  4351. }
  4352. },
  4353. getSelection: function () {
  4354. return this.W3CRange ? this.editArea.getSelection() : this.doc.selection;
  4355. },
  4356. clearSelection: function () {
  4357. var sel = this.getSelection();
  4358. if (!sel) {
  4359. return;
  4360. }
  4361. if (this.W3CRange) {
  4362. sel.removeAllRanges();
  4363. } else {
  4364. sel.empty();
  4365. }
  4366. return sel;
  4367. },
  4368. getRange: function () {
  4369. var selection = this.getSelection(), range = null;
  4370. if (this.W3CRange) {
  4371. if (selection.getRangeAt) {
  4372. range = selection.rangeCount ? selection.getRangeAt(0) : this.doc.createRange();
  4373. } else {
  4374. range = this.doc.createRange();
  4375. range.setStart(selection.anchorNode, selection.anchorOffset);
  4376. range.setEnd(selection.focusNode, selection.focusOffset);
  4377. if (range.collapsed !== selection.isCollapsed) {
  4378. range.setStart(selection.focusNode, selection.focusOffset);
  4379. range.setEnd(selection.anchorNode, selection.anchorOffset);
  4380. }
  4381. }
  4382. } else {
  4383. range = selection.createRange ? selection.createRange() : this.doc.createRange();
  4384. if (!range) {
  4385. range = this.doc.body.createTextRange();
  4386. }
  4387. }
  4388. this.range = range;
  4389. return range;
  4390. },
  4391. createRange: function () {
  4392. return this.W3CRange ? this.doc.createRange() : this.doc.body.createTextRange();
  4393. },
  4394. rangeCollapsed: function (range) {
  4395. return this.W3CRange ?
  4396. range.collapsed :
  4397. (!this.undefined(range.text) && range.text.length === 0 && range.boundingWidth === 0);
  4398. },
  4399. getRangeElement: function (range) {
  4400. return this.W3CRange ? this.getW3CRangeElement(range) : this.getIeRangeElement(range);
  4401. },
  4402. getIeRangeElement: function (range) {
  4403. var sType = this.getSelectionType(),
  4404. node;
  4405. if (!range) {
  4406. range = this.createRange();
  4407. }
  4408. switch (sType) {
  4409. case GB.selection.text:
  4410. node = range.parentElement();
  4411. break;
  4412. case GB.selection.element:
  4413. node = range.item(0);
  4414. break;
  4415. case GB.selection.none:
  4416. if (!this.undefined(range.parentElement)) {
  4417. node = range.parentElement();
  4418. } else {
  4419. node = range.item(0);
  4420. }
  4421. }
  4422. return node;
  4423. },
  4424. getW3CRangeElement: function (range) {
  4425. var ancestorContainer = range.commonAncestorContainer,
  4426. startContainer = range.startContainer,
  4427. startOffset = range.startOffset,
  4428. endContainer = range.endContainer,
  4429. endOffset = range.endOffset,
  4430. docFragment = null, node = startContainer;
  4431. if (GB.browser.msie || GB.browser.edge) {
  4432. if (!range.collapsed && ancestorContainer.nodeType === GB.node.element) {
  4433. if (ancestorContainer === endContainer) {
  4434. node = ancestorContainer.childNodes[endOffset - 1];
  4435. } else if (ancestorContainer === startContainer) {
  4436. node = ancestorContainer.childNodes[startOffset];
  4437. } else {
  4438. docFragment = range.cloneContents();
  4439. node = (docFragment.childNodes.length === 1) ? startContainer.nextSibling : ancestorContainer;
  4440. }
  4441. }
  4442. } else {
  4443. if (!range.collapsed
  4444. && startContainer.nodeType === GB.node.element
  4445. && startContainer === endContainer
  4446. && endOffset - startOffset === 1
  4447. && startContainer.hasChildNodes()) {
  4448. node = startContainer.childNodes[startOffset];
  4449. }
  4450. }
  4451. if (node.nodeType === GB.node.text) {
  4452. node = node.parentNode;
  4453. }
  4454. return node;
  4455. },
  4456. getSelectionType: function () {
  4457. var selection = this.getSelection(), type;
  4458. if (this.W3CRange) {
  4459. if (!selection) {
  4460. type = GB.selection.none;
  4461. } else if (selection.rangeCount && !selection.isCollapsed && !selection.toString()) {
  4462. type = GB.selection.element;
  4463. } else {
  4464. type = GB.selection.text;
  4465. }
  4466. } else {
  4467. switch (selection.type) {
  4468. case 'Text': type = GB.selection.text; break;
  4469. case 'Control': type = GB.selection.element; break;
  4470. default: type = GB.selection.none;
  4471. }
  4472. if (selection.createRange().parentElement) {
  4473. type = GB.selection.text;
  4474. }
  4475. }
  4476. return type;
  4477. },
  4478. windowOpen: function (popupName) {
  4479. this.editAreaFocus();
  4480. this.boxHideAll();
  4481. this.backupRange();
  4482. if (!(this.undefined(GB.popupWindow[popupName]))) {
  4483. var popup = GB.popupWindow[popupName];
  4484. if (popupName === 'ImageUpload' && window.File && window.FileReader && window.FileList && window.Blob) {
  4485. popup.tmpl = 'image.html5.html';
  4486. }
  4487. this.popupWinLoad(popup);
  4488. } else {
  4489. alert('사용할 수 없는 명령입니다.');
  4490. }
  4491. },
  4492. doCmd: function (cmd, opt) {
  4493. var self = this, range = this.range,
  4494. i, keyboard = '', command = '', pNode, node, tmpframe, tmpdoc, html, content,
  4495. hr, newHr, para, next = null, nNode, tagName, style, id, hRule, nodeType, css, found = false,
  4496. isEmpty = false, selectionType, selection, nodeRange,
  4497. cleanPaste = function () {
  4498. self.editAreaFocus();
  4499. var tmpDoc = self.cheditor.tmpdoc;
  4500. tmpDoc.execCommand('SelectAll');
  4501. tmpDoc.execCommand('Paste');
  4502. return self.cleanFromWord(tmpDoc);
  4503. },
  4504. isTextVisible = function (elem) {
  4505. return (!(elem.firstChild.nodeType === GB.node.text && elem.firstChild === elem.lastChild &&
  4506. elem.firstChild.nodeValue === ''));
  4507. };
  4508. this.editAreaFocus();
  4509. this.boxHideAll();
  4510. if (!range) {
  4511. return;
  4512. }
  4513. if (cmd === 'NewDocument' && opt == null) {
  4514. if (confirm('글 내용이 모두 사라집니다. 계속하시겠습니까?')) {
  4515. this.doc.body.innerHTML = '';
  4516. }
  4517. this.images = [];
  4518. this.editImages = {};
  4519. this.editAreaFocus();
  4520. this.toolbarUpdate();
  4521. this.initDefaultParagraphSeparator();
  4522. return;
  4523. }
  4524. if (cmd === 'ClearTag' && opt == null) {
  4525. if (confirm('모든 HTML 태그를 삭제합니다. 계속하시겠습니까?\n(P, DIV, BR 태그와 텍스트는 삭제하지 않습니다.)')) {
  4526. content = this.doc.body.innerHTML;
  4527. this.doc.body.innerHTML = content.replace(/<(\/?)([^>]*)>/g,
  4528. function (a, b, c) {
  4529. var el = c.toLowerCase().split(/ /)[0];
  4530. if (el !== 'p' && el !== 'div' && el !== 'br') {
  4531. return '';
  4532. }
  4533. return '<' + b + el + '>';
  4534. });
  4535. }
  4536. this.editAreaFocus();
  4537. this.toolbarUpdate();
  4538. return;
  4539. }
  4540. if (cmd === 'NewDocument' && opt == '1') {
  4541. this.doc.body.innerHTML = '';
  4542. this.images = [];
  4543. this.editImages = {};
  4544. this.editAreaFocus();
  4545. this.toolbarUpdate();
  4546. this.initDefaultParagraphSeparator();
  4547. return;
  4548. }
  4549. if (cmd === 'Print') {
  4550. this.editArea.print();
  4551. return;
  4552. }
  4553. if (cmd === 'PageBreak') {
  4554. this.printPageBreak();
  4555. this.editAreaFocus();
  4556. return;
  4557. }
  4558. selectionType = this.getSelectionType();
  4559. if (this.W3CRange || selectionType === GB.selection.none) {
  4560. range = this.doc;
  4561. }
  4562. if (!GB.browser.msie && (cmd === 'Cut' || cmd === 'Copy' || cmd === 'Paste')) {
  4563. if ((range.execCommand(cmd, false, opt)) !== true) {
  4564. switch (cmd) {
  4565. case 'Cut': keyboard = 'x'; command = '자르기'; break;
  4566. case 'Copy': keyboard = 'c'; command = '복사'; break;
  4567. case 'Paste': keyboard = 'v'; command = '붙이기'; break;
  4568. }
  4569. alert('사용하고 계신 브라우저는 보안 상의 이유로 \'' + command + '\' 명령을 사용하실 수 없습니다. \n\n' +
  4570. '키보드 단축키를 이용하여 주십시오.\n단축키: Windows: Ctrl+' + keyboard + ', Mac OS X: Command+' + keyboard);
  4571. this.editAreaFocus();
  4572. }
  4573. return;
  4574. }
  4575. try {
  4576. if (cmd === 'PasteFromWord') {
  4577. if (this.undefined(this.cheditor.tmpdoc)) {
  4578. tmpframe = this.doc.createElement('iframe');
  4579. tmpframe.setAttribute('contentEditable', 'true');
  4580. tmpframe.style.visibility = 'hidden';
  4581. tmpframe.style.height = tmpframe.style.width = '0px';
  4582. tmpframe.setAttribute('frameBorder', '0');
  4583. this.cheditor.editWrapper.appendChild(tmpframe);
  4584. tmpdoc = tmpframe.contentWindow.document;
  4585. tmpdoc.designMode = 'On';
  4586. tmpdoc.open();
  4587. tmpdoc.close();
  4588. this.cheditor.tmpdoc = tmpdoc;
  4589. }
  4590. if (this.W3CRange) {
  4591. html = cleanPaste();
  4592. // range = this.restoreRange();
  4593. this.insertNodeAtSelection(html);
  4594. } else {
  4595. range = this.getRange();
  4596. range.pasteHTML(cleanPaste());
  4597. range.select();
  4598. }
  4599. } else if (cmd === 'Paste') {
  4600. this.cheditor.paste = 'text';
  4601. this.handlePaste(null);
  4602. this.cheditor.paste = 'html';
  4603. } else if (cmd === 'InsertHorizontalRule') {
  4604. hr = this.doc.createElement('hr');
  4605. hr.style.height = '1px';
  4606. hr.style.backgroundColor = '#999';
  4607. hr.style.border = 'none';
  4608. this.unselectionElement(hr);
  4609. range = this.getRange();
  4610. if (this.W3CRange) {
  4611. range.insertNode(hr);
  4612. } else {
  4613. nodeType = this.getSelectionType();
  4614. id = this.makeRandomString();
  4615. range.execCommand('InsertHorizontalRule', false, id);
  4616. switch (nodeType) {
  4617. case GB.selection.none:
  4618. case GB.selection.text:
  4619. node = range.parentElement();
  4620. break;
  4621. case GB.selection.element:
  4622. node = range.item(0);
  4623. break;
  4624. default:
  4625. return;
  4626. }
  4627. newHr = this.$(id);
  4628. newHr.parentNode.replaceChild(hr, newHr);
  4629. }
  4630. hRule = hr;
  4631. pNode = hRule.parentNode;
  4632. para = this.makeSpacerElement();
  4633. while (pNode && GB.textFormatTags[pNode.nodeName.toLowerCase()]) {
  4634. pNode = pNode.parentNode;
  4635. }
  4636. tagName = pNode.tagName.toLowerCase();
  4637. if (GB.textFormatBlockTags[tagName]) {
  4638. if (hr.nextSibling) {
  4639. next = this.doc.createElement(tagName);
  4640. pNode.parentNode.insertBefore(next, pNode.nextSibling);
  4641. while (hr.nextSibling) {
  4642. if (hr.nextSibling.nodeType === GB.node.text && hr.nextSibling.nodeValue === '') {
  4643. hr = hr.nextSibling;
  4644. continue;
  4645. }
  4646. if (hr.nextSibling.parentNode !== pNode) {
  4647. node = hr.nextSibling.parentNode;
  4648. while (node !== pNode && GB.textFormatTags[node.nodeName.toLowerCase()]) {
  4649. nNode = this.doc.createElement(node.nodeName);
  4650. style = this.getCssValue(node);
  4651. if (style) {
  4652. for (i = 0; i < style.length; i++) {
  4653. nNode.style[style[i].name] = style[i].value;
  4654. }
  4655. }
  4656. if (next.hasChildNodes() === false) {
  4657. next.appendChild(nNode);
  4658. while (hr.nextSibling) {
  4659. nNode.appendChild(hr.nextSibling);
  4660. }
  4661. } else {
  4662. next.appendChild(nNode);
  4663. nNode.appendChild(next.firstChild);
  4664. }
  4665. node = node.parentNode;
  4666. }
  4667. } else {
  4668. next.appendChild(hr.nextSibling);
  4669. }
  4670. }
  4671. }
  4672. node = hr.parentNode;
  4673. pNode.parentNode.insertBefore(hRule, pNode.nextSibling);
  4674. while (node && node !== pNode) {
  4675. if (node.hasChildNodes() === false || (isTextVisible(node)) === false) {
  4676. nNode = node.parentNode;
  4677. node.parentNode.removeChild(node);
  4678. node = nNode;
  4679. continue;
  4680. }
  4681. node = node.parentNode;
  4682. }
  4683. if (pNode.hasChildNodes() === false || (isTextVisible(pNode)) === false) {
  4684. pNode.parentNode.replaceChild(para.cloneNode(true), pNode);
  4685. }
  4686. if (next === null || next.hasChildNodes() === false) {
  4687. hRule.parentNode.insertBefore(para.cloneNode(true), hRule.nextSibling);
  4688. }
  4689. node = hRule.nextSibling;
  4690. while (node.firstChild) {
  4691. node = node.firstChild;
  4692. }
  4693. if (node && node.nodeType !== GB.node.text) {
  4694. node = node.parentNode;
  4695. }
  4696. this.placeCaretAt(this.W3CRange ? node : hRule.nextSibling, true);
  4697. } else {
  4698. if (!hRule.previousSibling) {
  4699. hRule.parentNode.insertBefore(para.cloneNode(true), hRule);
  4700. }
  4701. if (!hRule.nextSibling) {
  4702. hRule.parentNode.insertBefore(para.cloneNode(true), hRule.nextSibling);
  4703. }
  4704. this.placeCaretAt(hRule.nextSibling, hRule.nextSibling.nodeType === GB.node.text);
  4705. }
  4706. } else {
  4707. switch (cmd) {
  4708. case 'JustifyLeft':
  4709. case 'JustifyCenter':
  4710. case 'JustifyRight':
  4711. case 'JustifyFull':
  4712. pNode = this.getRangeElement(this.range);
  4713. node = null;
  4714. if (GB.offElementTags[pNode.nodeName.toLowerCase()]) {
  4715. nodeRange = this.createRange();
  4716. selection = this.clearSelection();
  4717. if (this.W3CRange) {
  4718. nodeRange.selectNode(pNode);
  4719. selection.addRange(nodeRange);
  4720. } else {
  4721. nodeRange.moveToElementText(pNode);
  4722. nodeRange.select();
  4723. range = nodeRange;
  4724. }
  4725. }
  4726. // Caption
  4727. if (pNode.nodeName.toLowerCase() === 'img') {
  4728. if (pNode.parentNode.nodeName.toLowerCase() === 'figure') {
  4729. node = pNode.parentNode;
  4730. if (node.parentNode.nodeName.toLowerCase() === 'div') {
  4731. node = node.parentNode;
  4732. node.style.textAlign = GB.textAlign[cmd];
  4733. break;
  4734. }
  4735. }
  4736. } else if (pNode.nodeName.toLowerCase() === 'figure') {
  4737. node = pNode.parentNode;
  4738. if (node.nodeName.toLowerCase() === 'div') {
  4739. node.style.textAlign = GB.textAlign[cmd];
  4740. break;
  4741. }
  4742. }
  4743. do {
  4744. if (pNode.nodeName.toLowerCase() === 'li') {
  4745. node = pNode;
  4746. break;
  4747. }
  4748. pNode = pNode.parentNode;
  4749. } while (pNode && pNode.nodeName.toLowerCase() !== 'body');
  4750. if (node) {
  4751. node.style.textAlign = GB.textAlign[cmd];
  4752. break;
  4753. }
  4754. range.execCommand(cmd, false, opt);
  4755. pNode = this.getRangeElement(this.W3CRange ? this.getRange() : range);
  4756. while (pNode && pNode.nodeName.toLowerCase() !== 'body') {
  4757. if (typeof pNode.getAttribute !== 'undefined' && pNode.getAttribute('align')) {
  4758. node = pNode;
  4759. break;
  4760. } else {
  4761. css = this.getCssValue(pNode);
  4762. if (css) {
  4763. for (i = 0; i < css.length; i++) {
  4764. if (css[i].name === 'text-align') {
  4765. node = pNode;
  4766. break;
  4767. }
  4768. }
  4769. }
  4770. }
  4771. pNode = pNode.parentNode;
  4772. }
  4773. if (node) {
  4774. pNode.style.textAlign = GB.textAlign[cmd];
  4775. pNode.removeAttribute('align');
  4776. break;
  4777. }
  4778. break;
  4779. case 'InsertOrderedList':
  4780. case 'InsertUnOrderedList':
  4781. range.execCommand(cmd, false, opt);
  4782. if (this.W3CRange) {
  4783. range = this.getRange();
  4784. node = range.commonAncestorContainer;
  4785. if (node.nodeType === GB.node.element && node.lastChild &&
  4786. node.lastChild.nodeName.toLowerCase() === 'br') {
  4787. node.lastChild.className = this.cheditor.bogusSpacerName;
  4788. isEmpty = true;
  4789. }
  4790. found = false;
  4791. while (node) {
  4792. if (node.nodeName.toLowerCase() === 'ul' || node.nodeName.toLowerCase() === 'ol') {
  4793. found = true;
  4794. break;
  4795. }
  4796. node = node.parentNode;
  4797. }
  4798. if (found) {
  4799. node.style.listStyleType = '';
  4800. if (!GB.browser.msie) {
  4801. if (node.parentNode.nodeName.toLowerCase() === 'p' ||
  4802. node.parentNode.nodeName.toLowerCase() === 'div') {
  4803. pNode = node.parentNode;
  4804. if (pNode.lastChild && pNode.lastChild.nodeName.toLowerCase() === 'br') {
  4805. pNode.removeChild(pNode.lastChild);
  4806. }
  4807. if (pNode.firstChild === node && pNode.lastChild === node) {
  4808. pNode.parentNode.insertBefore(node, pNode);
  4809. pNode.parentNode.removeChild(pNode);
  4810. this.placeCaretAt(node.lastChild, isEmpty);
  4811. }
  4812. }
  4813. }
  4814. }
  4815. }
  4816. break;
  4817. default:
  4818. if (range.queryCommandSupported(cmd)) {
  4819. range.execCommand(cmd, false, opt);
  4820. }
  4821. }
  4822. }
  4823. } catch (e) {
  4824. alert(cmd + ': 지원되지 않는 명령입니다. ' + e.toString());
  4825. }
  4826. this.toolbarUpdate();
  4827. },
  4828. cleanFromWord: function (tmpDoc) {
  4829. var doc = tmpDoc.body.innerHTML;
  4830. doc = doc.replace(/MsoNormal/g, ''); doc = doc.replace(/<\\?\?xml[^>]*>/g, ''); doc = doc.replace(/<\/?o:p[^>]*>/g, '');
  4831. doc = doc.replace(/<\/?v:[^>]*>/g, ''); doc = doc.replace(/<\/?o:[^>]*>/g, ''); doc = doc.replace(/<\/?st1:[^>]*>/g, '');
  4832. doc = doc.replace(/<!--(.*)-->/g, ''); doc = doc.replace(/<!--(.*)>/g, ''); doc = doc.replace(/<!(.*)-->/g, '');
  4833. doc = doc.replace(/<\\?\?xml[^>]*>/g, ''); doc = doc.replace(/<\/?o:p[^>]*>/g, ''); doc = doc.replace(/<\/?v:[^>]*>/g, '');
  4834. doc = doc.replace(/<\/?o:[^>]*>/g, ''); doc = doc.replace(/<\/?st1:[^>]*>/g, ''); //doc = doc.replace(/lang=.?[^' >]*/ig, '');
  4835. doc = doc.replace(/type=.?[^' >]*/g, ''); doc = doc.replace(/href='#[^']*'/g, ''); doc = doc.replace(/href='#[^']*'/g, '');
  4836. doc = doc.replace(/name=.?[^' >]*/g, ''); doc = doc.replace(/ clear='all'/g, ''); doc = doc.replace(/id='[^']*'/g, '');
  4837. doc = doc.replace(/title='[^']*'/g, ''); doc = doc.replace(/\n/g, ''); doc = doc.replace(/\r/g, '');
  4838. doc = doc.replace(/mso\-[^'>;]*/g, ''); doc = doc.replace(/<p[^>]*/ig, '<p'); doc = doc.replace(/windowtext/ig, '#000000');
  4839. doc = doc.replace(/class=table/ig, ''); doc = doc.replace(/<span[^>]*<\/span>/ig, '');
  4840. return doc;
  4841. },
  4842. printPageBreak: function () {
  4843. var hr = document.createElement('hr'),
  4844. div = this.doc.createElement('div');
  4845. hr.style.pageBreakAfter = 'always';
  4846. hr.style.border = '1px #999 dotted';
  4847. this.insertHTML(hr);
  4848. div.appendChild(this.doc.createTextNode('\u00a0'));
  4849. this.insertHTML(div);
  4850. },
  4851. doCmdPaste: function (html) {
  4852. var range = null;
  4853. this.editAreaFocus();
  4854. if (!this.W3CRange) {
  4855. if (this.range.item) {
  4856. range = this.doc.body.createTextRange();
  4857. if (range) {
  4858. range.moveToElementText(this.range.item(0));
  4859. range.select();
  4860. this.range.item(0).outerHTML = html;
  4861. }
  4862. this.toolbarUpdate();
  4863. } else {
  4864. this.range.pasteHTML(html);
  4865. this.range.select();
  4866. }
  4867. } else {
  4868. this.insertNodeAtSelection(html);
  4869. }
  4870. },
  4871. getPreviousLeaf: function (node) {
  4872. var leaf;
  4873. while (!node.previousSibling) {
  4874. node = node.parentNode;
  4875. if (!node) {
  4876. return node;
  4877. }
  4878. }
  4879. leaf = node.previousSibling;
  4880. while (leaf.lastChild) {
  4881. leaf = leaf.lastChild;
  4882. }
  4883. return leaf;
  4884. },
  4885. getNextLeaf: function (node, breakNode) {
  4886. var leaf;
  4887. while (!node.nextSibling) {
  4888. node = node.parentNode;
  4889. if ((breakNode && breakNode === node) || !node) {
  4890. return node;
  4891. }
  4892. }
  4893. leaf = node.nextSibling;
  4894. if (breakNode && leaf === breakNode) {
  4895. return node;
  4896. }
  4897. while (leaf.firstChild) {
  4898. leaf = leaf.firstChild;
  4899. }
  4900. return leaf;
  4901. },
  4902. isTextVisible: function (text) {
  4903. var i, found = false, len = text.length;
  4904. for (i = 0; i < len; i++) {
  4905. if (text.charAt(i) !== ' ' && text.charAt(i) !== '\t' && text.charAt(i) !== '\r' && text.charAt(i) !== '\n') {
  4906. found = true;
  4907. break;
  4908. }
  4909. }
  4910. return found;
  4911. },
  4912. checkCssValue: function (elem, prop) {
  4913. var css = this.getCssValue(elem), i;
  4914. if (!css) {
  4915. return null;
  4916. }
  4917. for (i = 0; i < css.length; i++) {
  4918. if (css[i].name === prop) {
  4919. return css[i];
  4920. }
  4921. }
  4922. return null;
  4923. },
  4924. getCssValue: function (elem) {
  4925. var i, q, style = [], len, css;
  4926. css = elem.getAttribute('style');
  4927. if (!css) {
  4928. return null;
  4929. }
  4930. if (typeof css === 'object') {
  4931. css = css.cssText;
  4932. }
  4933. if (this.trimSpace(css) === '') {
  4934. return null;
  4935. }
  4936. css = css.replace(/;$/, '').split(';');
  4937. len = css.length;
  4938. for (i = 0; i < len; i++) {
  4939. q = css[i].split(':');
  4940. style.push({ 'name': this.trimSpace(q[0]).toLowerCase(), 'value': this.trimSpace(q[1]).toLowerCase() });
  4941. }
  4942. return style;
  4943. },
  4944. makeFontCss: function (cmd, opt, elem) {
  4945. switch (cmd) {
  4946. case 'font-size': elem.style.fontSize = opt; break;
  4947. case 'font-family': elem.style.fontFamily = opt; break;
  4948. case 'color': elem.style.color = opt; break;
  4949. case 'background-color': elem.style.backgroundColor = opt; break;
  4950. }
  4951. },
  4952. insertStartEndNode: function (range) {
  4953. var startNode = this.doc.createElement('span'),
  4954. startRange, endRange, endNode, collapsed, node = null;
  4955. startNode.id = 'startNode';
  4956. if (!this.W3CRange) {
  4957. startNode.appendChild(this.doc.createTextNode('\u200b'));
  4958. try {
  4959. endRange = range.duplicate();
  4960. startRange = range.duplicate();
  4961. endRange.collapse(false);
  4962. startRange.collapse(true);
  4963. } catch (e) {
  4964. node = this.getRangeElement(range);
  4965. if (node.nodeType === GB.node.element) {
  4966. } else {
  4967. return null;
  4968. }
  4969. }
  4970. endNode = startNode.cloneNode(true);
  4971. endNode.id = 'endNode';
  4972. if (node) {
  4973. node.parentNode.insertBefore(startNode, node);
  4974. node.parentNode.insertBefore(endNode, node.nextSibling);
  4975. collapsed = false;
  4976. } else {
  4977. collapsed = startRange.isEqual(endRange);
  4978. endRange.pasteHTML(endNode.outerHTML);
  4979. endRange.moveStart('character', -1);
  4980. endNode = endRange.parentElement();
  4981. if (collapsed || range.text.length === 0) {
  4982. endNode.parentNode.insertBefore(startNode, endNode);
  4983. } else {
  4984. startNode = endNode.cloneNode(true);
  4985. startNode.id = 'startNode';
  4986. startRange.pasteHTML(startNode.outerHTML);
  4987. startRange.moveStart('character', -1);
  4988. startNode = startRange.parentElement();
  4989. }
  4990. }
  4991. endRange = null;
  4992. startRange = null;
  4993. } else {
  4994. endRange = range.cloneRange();
  4995. startRange = range.cloneRange();
  4996. startRange.collapse(true);
  4997. endRange.collapse(false);
  4998. endNode = startNode.cloneNode(false);
  4999. endNode.id = 'endNode';
  5000. collapsed = range.collapsed;
  5001. if (collapsed) {
  5002. endRange.insertNode(endNode);
  5003. endNode.parentNode.insertBefore(startNode, endNode);
  5004. } else {
  5005. endRange.insertNode(endNode);
  5006. startRange.insertNode(startNode);
  5007. }
  5008. if (startNode.previousSibling && startNode.previousSibling.nodeType === GB.node.text &&
  5009. startNode.previousSibling.nodeValue === '') {
  5010. startNode.previousSibling.parentNode.removeChild(startNode.previousSibling);
  5011. }
  5012. if (endNode.nextSibling && endNode.nextSibling.nodeType === GB.node.text &&
  5013. endNode.nextSibling.nodeValue === '') {
  5014. endNode.nextSibling.parentNode.removeChild(endNode.nextSibling);
  5015. }
  5016. startRange.detach(); endRange.detach();
  5017. endRange = null; startRange = null;
  5018. }
  5019. return { startNode: startNode, endNode: endNode, collapsed: collapsed };
  5020. },
  5021. removeStartEndNode: function (nodes) {
  5022. if (nodes.startNode) {
  5023. nodes.startNode.parentNode.removeChild(nodes.startNode);
  5024. }
  5025. if (nodes.endNode) {
  5026. nodes.endNode.parentNode.removeChild(nodes.endNode);
  5027. }
  5028. },
  5029. clearCss: function (node, name) {
  5030. var i, css, styles = [];
  5031. if (!node || node.nodeType !== GB.node.element) {
  5032. return null;
  5033. }
  5034. css = this.getCssValue(node);
  5035. if (!css) {
  5036. return null;
  5037. }
  5038. node.removeAttribute('style');
  5039. for (i = 0; i < css.length; i++) {
  5040. if (css[i].name !== name) {
  5041. node.style[css[i].name] = css[i].value;
  5042. styles.push(css[i]);
  5043. }
  5044. }
  5045. return styles.length ? styles : null;
  5046. },
  5047. doCmdPopup: function (cmd, opt, checked) {
  5048. var self = this,
  5049. range, cursor, selectionType, pNode, node, found, isEmpty, span, endNode, startNode, i, endNodeAncestorRange,
  5050. startNodeRange, endNodeRange, compare, tNode, len, selection, child, css, tempNodes, endNodeAncestor,
  5051. backupRange, removeNodes = [], spanNodes = [], applyTextNodes = [], tailNodes = [], headNodes = [], rootNode = null,
  5052. zeroWidth = this.doc.createTextNode('\u200b'), inRange,
  5053. makeSpanText = function (elem, ancestor) {
  5054. if (self.undefined(ancestor)) {
  5055. ancestor = elem.parentNode;
  5056. }
  5057. span = self.doc.createElement('span');
  5058. self.makeFontCss(cmd, opt, span);
  5059. ancestor.insertBefore(span, elem);
  5060. span.appendChild(elem);
  5061. spanNodes.push(span);
  5062. return span;
  5063. },
  5064. searchTextNode = function (node, match) {
  5065. var i = 0, len = node.childNodes.length;
  5066. for (; i < len; i++) {
  5067. child = node.childNodes[i];
  5068. match = searchTextNode(child, match);
  5069. if (child === startNode) {
  5070. break;
  5071. }
  5072. if (child.nodeType === GB.node.text) {
  5073. match = true;
  5074. break;
  5075. }
  5076. if (child.nodeType === GB.node.element && child.hasChildNodes() === false &&
  5077. GB.textFormatTags[child.nodeName.toLowerCase()]) {
  5078. removeNodes.push(child);
  5079. }
  5080. }
  5081. return match;
  5082. },
  5083. compareBoundaryPoints = function (range, type, source) {
  5084. var values = {
  5085. 'StartToStart': 0, //Range.START_TO_START,
  5086. 'StartToEnd': 1, //Range.START_TO_END,
  5087. 'EndToEnd': 2, //Range.END_TO_END,
  5088. 'EndToStart': 3 //Range.END_TO_START
  5089. };
  5090. if (self.W3CRange) {
  5091. return range.compareBoundaryPoints(values[type], source);
  5092. }
  5093. type = type === 'StartToEnd' ? 'EndToStart' : (type === 'EndToStart' ? 'StartToEnd' : type);
  5094. return range.compareEndPoints(type, source);
  5095. },
  5096. rangeSelectNode = function (range, node) {
  5097. if (self.W3CRange) {
  5098. range.selectNode(node);
  5099. } else {
  5100. if (node.nodeType === GB.node.text) {
  5101. node = node.parentNode;
  5102. }
  5103. range.moveToElementText(node);
  5104. }
  5105. },
  5106. clearPreviousLeaf = function (node) {
  5107. var leaf, css = [];
  5108. while (!node.previousSibling) {
  5109. node = node.parentNode;
  5110. if (!node || node.nodeName.toLowerCase() === 'body') {
  5111. return null;
  5112. }
  5113. }
  5114. leaf = node.previousSibling;
  5115. while (leaf.lastChild && leaf.nodeType === GB.node.element && leaf !== startNode) {
  5116. rangeSelectNode(cursor, leaf);
  5117. compare = compareBoundaryPoints(cursor, 'StartToStart', startNodeRange);
  5118. if (compare === 1) {
  5119. css = self.clearCss(leaf, cmd);
  5120. if (!css && (leaf.nodeName.toLowerCase() === 'span' || leaf.nodeName.toLowerCase() === 'font')) {
  5121. while (leaf.firstChild) {
  5122. leaf.parentNode.insertBefore(leaf.firstChild, leaf);
  5123. }
  5124. removeNodes.push(leaf);
  5125. break;
  5126. }
  5127. } else if (compare === 0) {
  5128. self.clearCss(leaf, cmd);
  5129. if (!rootNode && leaf.nodeName.toLowerCase() === 'span') {
  5130. rootNode = leaf;
  5131. }
  5132. } else { // -1
  5133. node = startNode;
  5134. found = false;
  5135. while (node) {
  5136. if (node.nodeType === GB.node.text) {
  5137. found = true;
  5138. break;
  5139. }
  5140. node = checkPreviousLeaf(node, leaf);
  5141. }
  5142. if (!found) {
  5143. self.clearCss(leaf, cmd);
  5144. if (!rootNode && leaf.nodeName.toLowerCase() === 'span') {
  5145. rootNode = leaf;
  5146. }
  5147. }
  5148. }
  5149. leaf = leaf.lastChild;
  5150. }
  5151. if (leaf.nodeType === GB.node.text && self.isTextVisible(leaf.nodeValue)) {
  5152. applyTextNodes.push(leaf);
  5153. }
  5154. return leaf;
  5155. },
  5156. checkPreviousLeaf = function (node, breakNode) {
  5157. var leaf;
  5158. while (!node.previousSibling) {
  5159. node = node.parentNode;
  5160. if (node === breakNode || node.nodeName.toLowerCase() === 'body') {
  5161. return null;
  5162. }
  5163. }
  5164. leaf = node.previousSibling;
  5165. while (leaf.lastChild) {
  5166. leaf = leaf.lastChild;
  5167. }
  5168. return leaf;
  5169. },
  5170. checkInRange = function (range, source) {
  5171. return (typeof range.inRange !== 'undefined') ? range.inRange(source) :
  5172. (compareBoundaryPoints(range, 'StartToStart', source) < 1
  5173. && compareBoundaryPoints(range, 'EndToEnd', source) > -1);
  5174. },
  5175. checkNextLeaf = function (node) {
  5176. var leaf, inRange;
  5177. while (!node.nextSibling) {
  5178. node = node.parentNode;
  5179. if (!node || node.nodeName.toLowerCase() === 'body') {
  5180. return null;
  5181. }
  5182. rangeSelectNode(cursor, node);
  5183. inRange = checkInRange(cursor, endNodeRange);
  5184. if (inRange) {
  5185. inRange = checkInRange(cursor, startNodeRange);
  5186. if (!inRange) {
  5187. tailNodes.push(node);
  5188. } else {
  5189. headNodes.push(node);
  5190. }
  5191. }
  5192. if (node === endNodeAncestor) {
  5193. return null;
  5194. }
  5195. }
  5196. leaf = node.nextSibling;
  5197. if (leaf.nodeType === GB.node.text || !endNodeAncestor) {
  5198. return null;
  5199. }
  5200. rangeSelectNode(cursor, leaf);
  5201. inRange = checkInRange(endNodeAncestorRange, cursor);
  5202. if (!inRange) {
  5203. return null;
  5204. }
  5205. while (leaf.firstChild) {
  5206. leaf = leaf.firstChild;
  5207. }
  5208. if (leaf.nodeType === GB.node.text) {
  5209. tailNodes = [];
  5210. return null;
  5211. }
  5212. return leaf;
  5213. },
  5214. checkParentSpan = function (node) {
  5215. var len = spanNodes.length, i = 0;
  5216. for (; i < len; i++) {
  5217. if (spanNodes[i] === node) {
  5218. return true;
  5219. }
  5220. }
  5221. return false;
  5222. };
  5223. this.editAreaFocus();
  5224. backupRange = this.restoreRange();
  5225. selectionType = this.getSelectionType();
  5226. if (this.W3CRange) {
  5227. range = this.doc;
  5228. } else {
  5229. range = (selectionType === GB.selection.none) ? this.doc : backupRange;
  5230. }
  5231. try {
  5232. if (cmd === 'LineHeight') {
  5233. this.applyLineHeight(opt);
  5234. } else {
  5235. if (cmd === 'InsertOrderedList' || cmd === 'InsertUnOrderedList') {
  5236. if (checked !== true) {
  5237. range.execCommand(cmd, false, opt);
  5238. if (!GB.browser.msie) {
  5239. range = this.getRange();
  5240. node = range.commonAncestorContainer;
  5241. found = isEmpty = false;
  5242. if (node.nodeType === GB.node.element && node.lastChild &&
  5243. node.lastChild.nodeName.toLowerCase() === 'br') {
  5244. node.lastChild.className = this.cheditor.bogusSpacerName;
  5245. isEmpty = true;
  5246. }
  5247. while (node) {
  5248. if (node.nodeName.toLowerCase() === 'ul' || node.nodeName.toLowerCase() === 'ol') {
  5249. found = true;
  5250. break;
  5251. }
  5252. node = node.parentNode;
  5253. }
  5254. if (found) {
  5255. if (node.parentNode.nodeName.toLowerCase() === 'p' ||
  5256. node.parentNode.nodeName.toLowerCase() === 'div') {
  5257. pNode = node.parentNode;
  5258. if (pNode.lastChild && pNode.lastChild.nodeName.toLowerCase() === 'br') {
  5259. pNode.removeChild(pNode.lastChild);
  5260. }
  5261. if (pNode.firstChild === node && pNode.lastChild === node) {
  5262. pNode.parentNode.insertBefore(node, pNode);
  5263. pNode.parentNode.removeChild(pNode);
  5264. this.placeCaretAt(node.lastChild, isEmpty);
  5265. }
  5266. }
  5267. }
  5268. }
  5269. }
  5270. cursor = this.getRange();
  5271. pNode = this.W3CRange ? cursor.commonAncestorContainer : cursor.parentElement();
  5272. if (pNode.nodeType === GB.node.text) {
  5273. pNode = pNode.parentNode;
  5274. }
  5275. while (pNode) {
  5276. if (pNode.nodeName.toLowerCase() === 'ol' || pNode.nodeName.toLowerCase() === 'ul') {
  5277. if (opt === 'desc' || opt === 'decimal') {
  5278. opt = '';
  5279. }
  5280. pNode.style.listStyleType = opt;
  5281. break;
  5282. }
  5283. pNode = pNode.parentNode;
  5284. }
  5285. } else if (cmd === 'FontSize' || cmd === 'FontName' || cmd === 'ForeColor' || cmd === 'BackColor') {
  5286. if (cmd === 'ForeColor' || cmd === 'BackColor') {
  5287. opt = this.colorConvert(opt, 'hex');
  5288. } else if (cmd === 'FontName' && opt === '맑은 고딕') {
  5289. opt += ', "Malgun Gothic"';
  5290. }
  5291. cmd = GB.fontStyle[cmd];
  5292. range = this.getRange();
  5293. tempNodes = this.insertStartEndNode(range);
  5294. startNode = tempNodes.startNode;
  5295. endNode = tempNodes.endNode;
  5296. cursor = this.createRange();
  5297. startNodeRange = this.createRange();
  5298. rangeSelectNode(startNodeRange, startNode);
  5299. endNodeRange = this.createRange();
  5300. endNodeAncestorRange = this.createRange();
  5301. if (!tempNodes.collapsed) {
  5302. tailNodes = [];
  5303. endNodeAncestor = null;
  5304. rangeSelectNode(endNodeRange, endNode);
  5305. node = endNode.parentNode;
  5306. while (node && node.nodeName.toLowerCase() !== 'body') {
  5307. endNodeAncestor = node;
  5308. node = node.parentNode;
  5309. }
  5310. if (endNodeAncestor) {
  5311. rangeSelectNode(endNodeAncestorRange, endNodeAncestor);
  5312. }
  5313. node = endNode;
  5314. while (node) {
  5315. node = checkNextLeaf(node);
  5316. }
  5317. for (i = 0; i < tailNodes.length; i++) {
  5318. this.clearCss(tailNodes[i], cmd);
  5319. }
  5320. node = endNode;
  5321. while (node && node !== startNode) {
  5322. node = clearPreviousLeaf(node);
  5323. }
  5324. if (headNodes.length) {
  5325. found = false;
  5326. node = startNode;
  5327. while (node) {
  5328. if (node.nodeType === GB.node.text) {
  5329. found = true;
  5330. break;
  5331. }
  5332. node = checkPreviousLeaf(node, endNodeAncestor);
  5333. }
  5334. if (!found) {
  5335. for (i = 0; i < headNodes.length; i++) {
  5336. self.clearCss(headNodes[i], cmd);
  5337. css = self.getCssValue(headNodes[i]);
  5338. if (!css && headNodes[i].nodeName.toLowerCase() === 'span') {
  5339. child = headNodes[i];
  5340. while (child.firstChild) {
  5341. child.parentNode.insertBefore(child.firstChild, child);
  5342. }
  5343. child.parentNode.removeChild(child);
  5344. headNodes.splice(i);
  5345. }
  5346. }
  5347. }
  5348. }
  5349. for (i = 0; i < removeNodes.length; i++) {
  5350. removeNodes[i].parentNode.removeChild(removeNodes[i]);
  5351. }
  5352. removeNodes = [];
  5353. len = applyTextNodes.length;
  5354. if (rootNode) {
  5355. rangeSelectNode(startNodeRange, rootNode);
  5356. }
  5357. for (i = 0; i < len; i++) {
  5358. tNode = applyTextNodes[i];
  5359. if (tNode.previousSibling && tNode.previousSibling.nodeType === GB.node.text) {
  5360. if (applyTextNodes[i + 1] && tNode.previousSibling === applyTextNodes[i + 1]) {
  5361. applyTextNodes[i + 1].nodeValue += tNode.nodeValue;
  5362. tNode.parentNode.removeChild(tNode);
  5363. } else {
  5364. tNode.nodeValue = tNode.previousSibling.nodeValue + tNode.nodeValue;
  5365. tNode.previousSibling.parentNode.removeChild(tNode.previousSibling);
  5366. i--;
  5367. }
  5368. continue;
  5369. }
  5370. pNode = tNode.parentNode;
  5371. if (rootNode) {
  5372. rangeSelectNode(cursor, pNode);
  5373. inRange = checkInRange(startNodeRange, cursor);
  5374. if (inRange) {
  5375. self.makeFontCss(cmd, '', pNode);
  5376. self.makeFontCss(cmd, opt, rootNode);
  5377. continue;
  5378. }
  5379. }
  5380. if (pNode.nodeName.toLowerCase() === 'span'
  5381. && (pNode.firstChild === tNode || pNode.firstChild === startNode)
  5382. && (pNode.lastChild === tNode || pNode.lastChild === endNode)) {
  5383. self.makeFontCss(cmd, opt, pNode);
  5384. spanNodes.push(pNode);
  5385. continue;
  5386. }
  5387. makeSpanText(tNode);
  5388. }
  5389. len = spanNodes.length;
  5390. for (i = 0; i < len; i++) {
  5391. child = spanNodes[i];
  5392. pNode = child.parentNode;
  5393. if (pNode.nodeName.toLowerCase() === 'span') {
  5394. if (checkParentSpan(pNode)) {
  5395. self.makeFontCss(cmd, '', child);
  5396. css = self.getCssValue(child);
  5397. if (!css) {
  5398. while (child.firstChild) {
  5399. pNode.insertBefore(child.firstChild, child);
  5400. }
  5401. pNode.removeChild(child);
  5402. continue;
  5403. }
  5404. }
  5405. while (pNode && pNode.nodeName.toLowerCase() === 'span') {
  5406. if (pNode.firstChild === child && pNode.lastChild === child) {
  5407. css = self.getCssValue(pNode);
  5408. if (css) {
  5409. self.makeFontCss(cmd, '', pNode);
  5410. css = self.getCssValue(pNode);
  5411. if (!css) {
  5412. pNode.parentNode.insertBefore(child, pNode);
  5413. pNode.parentNode.removeChild(pNode);
  5414. pNode = child;
  5415. continue;
  5416. }
  5417. }
  5418. }
  5419. pNode = pNode.parentNode;
  5420. }
  5421. }
  5422. }
  5423. if (this.W3CRange) {
  5424. selection = this.getSelection();
  5425. if (selection.rangeCount > 0) {
  5426. selection.removeAllRanges();
  5427. }
  5428. range = this.createRange();
  5429. range.setStartAfter(startNode);
  5430. range.setEndBefore(endNode);
  5431. selection.addRange(range);
  5432. } else {
  5433. startNodeRange = this.createRange();
  5434. endNodeRange = startNodeRange.duplicate();
  5435. startNodeRange.moveToElementText(startNode);
  5436. endNodeRange.moveToElementText(endNode);
  5437. startNodeRange.setEndPoint('StartToEnd', startNodeRange);
  5438. startNodeRange.setEndPoint('EndToStart', endNodeRange);
  5439. startNodeRange.select();
  5440. }
  5441. } else {
  5442. pNode = startNode.parentNode;
  5443. found = false;
  5444. while (pNode && pNode.nodeName.toLowerCase() === 'span' && !found) {
  5445. css = self.getCssValue(pNode);
  5446. if (css) {
  5447. len = css.length;
  5448. for (i = 0; i < len; i++) {
  5449. if (css[i].name === cmd && css[i].value === opt) {
  5450. found = true;
  5451. break;
  5452. }
  5453. }
  5454. }
  5455. pNode = pNode.parentNode;
  5456. }
  5457. if (!found) {
  5458. span = this.doc.createElement('span');
  5459. this.makeFontCss(cmd, opt, span);
  5460. span.appendChild(zeroWidth);
  5461. endNode.parentNode.insertBefore(span, endNode);
  5462. if (this.W3CRange) {
  5463. selection = this.getSelection();
  5464. selection.collapse(zeroWidth, 1);
  5465. } else {
  5466. range = this.getRange();
  5467. range.moveToElementText(span);
  5468. range.collapse(false);
  5469. range.select();
  5470. }
  5471. }
  5472. }
  5473. this.removeStartEndNode(tempNodes);
  5474. } else {
  5475. range.execCommand(cmd, false, opt);
  5476. }
  5477. }
  5478. } catch (e) {
  5479. alert(e.toString());
  5480. }
  5481. this.toolbarUpdate();
  5482. this.boxHideAll();
  5483. },
  5484. modifyImage: function (img) {
  5485. var self = this,
  5486. idx, div, ico, inputCaption, wrapTextSpan, wrapTextCheckBox, wrapTextIcon, wrapTextChecked,
  5487. width = 0, height = 0, wrapElem, currentCaption = '', caption = null, inputAlt, inputTitle, cssFloat,
  5488. wrapperClassName = 'cheditor-caption-wrapper',
  5489. figureClassName = 'cheditor-caption',
  5490. figCaptionClassName = 'cheditor-caption-text',
  5491. imageWidthOpt = {
  5492. orig: { size: 'normal', desc: '원본 크기' },
  5493. fitpage: { size: '100%', desc: '페이지 크기에 맞춤' },
  5494. px160: { size: 160, desc: '썸네일, 160 픽셀' },
  5495. px320: { size: 320, desc: '작은 크기, 320 픽셀' },
  5496. px640: { size: 640, desc: '중간 크기, 640 픽셀' },
  5497. px1024: { size: 1024, desc: '크게, 1024 픽셀' },
  5498. px1600: { size: 1600, desc: '아주 크게, 1600 픽셀' }
  5499. },
  5500. captionAlignOpt = { left: '왼쪽', center: '가운데', right: '오른쪽' },
  5501. imageFloatOpt = {
  5502. left: {
  5503. value: '왼쪽',
  5504. input: null
  5505. },
  5506. right: {
  5507. value: '오른쪽',
  5508. input: null
  5509. }
  5510. },
  5511. fmSelectWidth = document.createElement('select'),
  5512. fmSelectCaptionAlign = document.createElement('select'),
  5513. onChangeEventHandler = function () {
  5514. if (self.editImages[img.src] && self.editImages[img.src].width) {
  5515. width = self.editImages[img.src].width;
  5516. if (self.editImages[img.src] && self.editImages[img.src].height) {
  5517. height = self.editImages[img.src].height;
  5518. } else {
  5519. height = img.height;
  5520. }
  5521. } else if (img.width) {
  5522. width = img.width;
  5523. } else {
  5524. return;
  5525. }
  5526. switch (this.value) {
  5527. case 'orig':
  5528. width = width + 'px';
  5529. height = (height || img.height) + 'px';
  5530. break;
  5531. case 'fitpage':
  5532. width = '100%';
  5533. height = 'auto';
  5534. break;
  5535. default:
  5536. width = imageWidthOpt[this.value].size;
  5537. if (img.height) {
  5538. height = Math.round((img.height * width) / img.width) + 'px';
  5539. }
  5540. width += 'px';
  5541. }
  5542. if (width) {
  5543. img.style.width = width;
  5544. if (caption && caption.figure) {
  5545. caption.figure.style.width = width;
  5546. }
  5547. }
  5548. if (height) {
  5549. img.style.height = height;
  5550. }
  5551. },
  5552. setCssFloat = function (elem, css) {
  5553. if (typeof elem.style.styleFloat === 'undefined') {
  5554. elem.style.cssFloat = css;
  5555. } else {
  5556. elem.style.styleFloat = css;
  5557. }
  5558. },
  5559. getCssFloat = function (elem) {
  5560. return (typeof elem.style.styleFloat === 'undefined') ? elem.style.cssFloat : elem.style.styleFloat;
  5561. },
  5562. clearCssFloat = function (elem) {
  5563. setCssFloat(elem, '');
  5564. elem.style.marginLeft = '';
  5565. elem.style.marginRight = '';
  5566. },
  5567. createInputForm = function (type, name, value, classname) {
  5568. var input = document.createElement('input');
  5569. input.setAttribute('type', type);
  5570. input.setAttribute('name', name);
  5571. input.setAttribute('value', value);
  5572. input.className = classname;
  5573. return input;
  5574. },
  5575. applyWrapText = function (elem) {
  5576. if (!elem) {
  5577. return;
  5578. }
  5579. wrapElem = (caption && caption.wrapper) ? caption.wrapper : img;
  5580. if (elem.checked) {
  5581. imageFloatOpt[(elem.name === 'left' ? 'right' : 'left')].input.checked = false;
  5582. setCssFloat(wrapElem, elem.name);
  5583. if (elem.name === 'left') {
  5584. wrapElem.style.marginRight = '1em';
  5585. wrapElem.style.marginLeft = '';
  5586. } else {
  5587. wrapElem.style.marginLeft = '1em';
  5588. wrapElem.style.marginRight = '';
  5589. }
  5590. if (caption && caption.wrapper) {
  5591. clearCssFloat(img);
  5592. }
  5593. } else {
  5594. clearCssFloat(wrapElem);
  5595. }
  5596. },
  5597. getCaptionNodes = function (img) {
  5598. var nodes = { figure: null, figCaption: [], captionText: '', img: null, wrapper: null },
  5599. pNode, node;
  5600. pNode = img.parentNode;
  5601. if (!pNode || pNode.nodeName.toLowerCase() !== 'figure') {
  5602. return null;
  5603. }
  5604. nodes.figure = pNode;
  5605. nodes.figCaption = pNode.getElementsByTagName('figcaption');
  5606. for (idx = 0; idx < nodes.figCaption.length; idx++) {
  5607. node = nodes.figCaption[idx].firstChild;
  5608. while (node) {
  5609. if (node.nodeType === GB.node.text) {
  5610. nodes.captionText += self.trimSpace(node.nodeValue);
  5611. }
  5612. node = node.nextSibling;
  5613. }
  5614. }
  5615. if (pNode.parentNode.nodeName.toLowerCase() === 'div' && pNode.parentNode.className === wrapperClassName) {
  5616. nodes.wrapper = pNode.parentNode;
  5617. }
  5618. nodes.img = img;
  5619. return nodes;
  5620. },
  5621. applyAlt = function () {
  5622. var alt = self.trimSpace(inputAlt.value);
  5623. if (alt !== '') {
  5624. img.setAttribute('alt', alt);
  5625. }
  5626. self.removeEvent(inputAlt, 'blur', applyAlt);
  5627. self.cheditor.modifyState = false;
  5628. },
  5629. applyTitle = function () {
  5630. var title = self.trimSpace(inputTitle.value);
  5631. if (title !== '') {
  5632. img.setAttribute('title', title);
  5633. }
  5634. self.removeEvent(inputTitle, 'blur', applyTitle);
  5635. self.cheditor.modifyState = false;
  5636. },
  5637. applyCaption = function () {
  5638. var figure = self.doc.createElement('figure'),
  5639. figCaption = self.doc.createElement('figcaption'),
  5640. wrapper = self.doc.createElement('div'),
  5641. pNode = img.parentNode, i, para = self.doc.createElement('p');
  5642. self.removeEvent(inputCaption, 'blur', applyCaption);
  5643. wrapper.className = wrapperClassName;
  5644. figure.className = figureClassName;
  5645. figCaption.className = figCaptionClassName;
  5646. this.value = self.trimSpace(inputCaption.value);
  5647. if (!self.isTextVisible(this.value) && caption) {
  5648. caption.wrapper.parentNode.insertBefore(para, caption.wrapper);
  5649. para.appendChild(caption.img);
  5650. cssFloat = getCssFloat(caption.wrapper);
  5651. caption.wrapper.parentNode.removeChild(caption.wrapper);
  5652. caption = getCaptionNodes(img);
  5653. if (cssFloat && (cssFloat === 'left' || cssFloat === 'right')) {
  5654. applyWrapText(imageFloatOpt[cssFloat].input);
  5655. }
  5656. self.cheditor.modifyState = false;
  5657. return;
  5658. }
  5659. if (currentCaption === this.value) {
  5660. self.cheditor.modifyState = false;
  5661. return;
  5662. }
  5663. if (caption && caption.figure) {
  5664. for (i = 0; i < caption.figCaption.length; i++) {
  5665. caption.figure.removeChild(caption.figCaption[i]);
  5666. }
  5667. figure = caption.figure;
  5668. } else {
  5669. if (pNode.nodeName.toLowerCase() !== 'body') {
  5670. pNode.parentNode.insertBefore(wrapper, pNode.nextSibling);
  5671. } else {
  5672. pNode.insertBefore(wrapper, img);
  5673. }
  5674. if (self.config.imgCaptionWrapper !== '') {
  5675. wrapper.setAttribute('style', self.config.imgCaptionWrapper);
  5676. }
  5677. wrapper.appendChild(figure);
  5678. figure.setAttribute('style', self.config.imgCaptionFigure);
  5679. figure.style.display = 'inline-block';
  5680. figure.style.width = img.width;
  5681. figure.appendChild(img);
  5682. para.appendChild(self.createNbspTextNode());
  5683. wrapper.parentNode.insertBefore(para, wrapper.nextSibling);
  5684. }
  5685. figure.appendChild(figCaption);
  5686. figCaption.setAttribute('style', self.config.imgCaptionText);
  5687. figCaption.appendChild(self.doc.createTextNode(this.value));
  5688. if (!pNode.hasChildNodes()) {
  5689. pNode.parentNode.removeChild(pNode);
  5690. }
  5691. caption = getCaptionNodes(img);
  5692. cssFloat = getCssFloat(img);
  5693. if (cssFloat && (cssFloat === 'left' || cssFloat === 'right')) {
  5694. applyWrapText(imageFloatOpt[cssFloat].input);
  5695. }
  5696. self.cheditor.modifyState = false;
  5697. };
  5698. for (idx in imageWidthOpt) {
  5699. if (imageWidthOpt.hasOwnProperty(idx)) {
  5700. fmSelectWidth.options[fmSelectWidth.options.length] = new Option(imageWidthOpt[idx].desc, idx);
  5701. }
  5702. }
  5703. fmSelectWidth.onchange = onChangeEventHandler;
  5704. caption = getCaptionNodes(img);
  5705. div = document.createElement('div');
  5706. div.style.textAlign = 'left';
  5707. ico = new Image();
  5708. ico.src = this.config.iconPath + 'image_resize.png';
  5709. ico.className = 'cheditor-ico';
  5710. div.appendChild(ico);
  5711. div.appendChild(fmSelectWidth);
  5712. wrapTextChecked = getCssFloat((caption && caption.wrapper) ? caption.wrapper : img);
  5713. for (idx in imageFloatOpt) {
  5714. if (imageFloatOpt.hasOwnProperty(idx)) {
  5715. wrapTextCheckBox = createInputForm('checkbox', idx, '1', 'wrap-checked');
  5716. wrapTextCheckBox.setAttribute('id', 'idWrapText-' + idx);
  5717. wrapTextCheckBox.onclick = function () {
  5718. applyWrapText(this);
  5719. };
  5720. imageFloatOpt[idx].input = wrapTextCheckBox;
  5721. wrapTextSpan = document.createElement('span');
  5722. wrapTextIcon = new Image();
  5723. wrapTextSpan.className = 'wrap-text-desc';
  5724. if (idx === 'left') {
  5725. wrapTextSpan.style.marginLeft = '20px';
  5726. }
  5727. if (wrapTextChecked === idx) {
  5728. wrapTextCheckBox.checked = 'checked';
  5729. }
  5730. wrapTextSpan.appendChild(wrapTextCheckBox);
  5731. wrapTextIcon.className = 'cheditor-ico';
  5732. wrapTextIcon.src = this.config.iconPath + 'image_align_' + idx + '_wt.png';
  5733. wrapTextSpan.appendChild(wrapTextIcon);
  5734. div.appendChild(wrapTextSpan);
  5735. }
  5736. }
  5737. if (self.undefined(self.editImages[img.src])) {
  5738. self.editImages[img.src] = { width: img.width, height: img.height };
  5739. }
  5740. div.appendChild(document.createTextNode('\u00a0\u00a0Alt:'));
  5741. inputAlt = createInputForm('text', 'inputAlt', '', 'user-input-alt');
  5742. inputAlt.onfocus = function () {
  5743. self.cheditor.modifyState = true;
  5744. self.addEvent(inputAlt, 'blur', applyAlt);
  5745. };
  5746. div.appendChild(inputAlt);
  5747. if (img.getAttribute('alt')) {
  5748. inputAlt.value = img.getAttribute('alt');
  5749. }
  5750. div.appendChild(document.createTextNode('타이틀:'));
  5751. inputTitle = createInputForm('text', 'inputTitle', '', 'user-input-alt');
  5752. inputTitle.onfocus = function () {
  5753. self.cheditor.modifyState = true;
  5754. self.addEvent(inputTitle, 'blur', applyTitle);
  5755. };
  5756. div.appendChild(inputTitle);
  5757. if (img.getAttribute('title')) {
  5758. inputTitle.value = img.getAttribute('title');
  5759. }
  5760. div.appendChild(document.createElement('br'));
  5761. div.appendChild(document.createTextNode('사진 캡션:'));
  5762. inputCaption = createInputForm('text', 'inputCaption', '', 'user-input-caption');
  5763. inputCaption.onfocus = function () {
  5764. caption = getCaptionNodes(img);
  5765. self.cheditor.modifyState = true;
  5766. self.addEvent(inputCaption, 'blur', applyCaption);
  5767. };
  5768. div.appendChild(inputCaption);
  5769. div.appendChild(document.createTextNode('캡션 텍스트 정렬:'));
  5770. for (idx in captionAlignOpt) {
  5771. if (captionAlignOpt.hasOwnProperty(idx)) {
  5772. fmSelectCaptionAlign.options[fmSelectCaptionAlign.options.length] = new Option(captionAlignOpt[idx], idx);
  5773. if (caption && caption.figCaption[0] && caption.figCaption[0].style.textAlign) {
  5774. if (idx === caption.figCaption[0].style.textAlign) {
  5775. fmSelectCaptionAlign.options[fmSelectCaptionAlign.options.length - 1].selected = true;
  5776. }
  5777. }
  5778. }
  5779. }
  5780. fmSelectCaptionAlign.className = 'caption-align';
  5781. fmSelectCaptionAlign.onchange = function () {
  5782. caption = getCaptionNodes(img);
  5783. if (!caption) {
  5784. return;
  5785. }
  5786. for (idx = 0; idx < caption.figCaption.length; idx++) {
  5787. caption.figCaption[idx].style.textAlign = this.value;
  5788. }
  5789. };
  5790. div.appendChild(fmSelectCaptionAlign);
  5791. if (caption && caption.captionText) {
  5792. currentCaption = self.trimSpace(caption.captionText);
  5793. inputCaption.value = currentCaption;
  5794. }
  5795. while (self.cheditor.editBlock.firstChild) {
  5796. self.cheditor.editBlock.removeChild(self.cheditor.editBlock.firstChild);
  5797. }
  5798. self.cheditor.editBlock.appendChild(div);
  5799. },
  5800. modifyCell: function (ctd) {
  5801. var self = this,
  5802. ctb = ctd,
  5803. ctr = ctb,
  5804. tm = [], i, jr, j, jh, jv, rowIndex = 0, realIndex = 0, newc, newr, nc, tempr, rows, span, icon,
  5805. div = document.createElement('div'),
  5806. getCellMatrix = function () {
  5807. rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr');
  5808. for (i = 0; i < rows.length; i++) {
  5809. tm[i] = [];
  5810. }
  5811. for (i = 0; i < rows.length; i++) {
  5812. jr = 0;
  5813. for (j = 0; j < rows[i].cells.length; j++) {
  5814. while (!(self.undefined(tm[i][jr]))) {
  5815. jr++;
  5816. }
  5817. for (jh = jr; jh < jr + (rows[i].cells[j].colSpan || 1) ; jh++) {
  5818. for (jv = i; jv < i + (rows[i].cells[j].rowSpan || 1) ; jv++) {
  5819. tm[jv][jh] = (jv === i) ? rows[i].cells[j].cellIndex : -1;
  5820. }
  5821. }
  5822. }
  5823. }
  5824. return tm;
  5825. },
  5826. insertColumn = function () {
  5827. tm = getCellMatrix();
  5828. rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr');
  5829. if (ctr.rowIndex >= 0) {
  5830. rowIndex = ctr.rowIndex;
  5831. } else {
  5832. for (i = 0; i < rows.length; i++) {
  5833. if (rows[i] === ctr) {
  5834. rowIndex = i;
  5835. break;
  5836. }
  5837. }
  5838. }
  5839. for (j = 0; j < tm[rowIndex].length; j++) {
  5840. if (tm[rowIndex][j] === ctd.cellIndex) {
  5841. realIndex = j;
  5842. break;
  5843. }
  5844. }
  5845. for (i = 0; i < rows.length; i++) {
  5846. if (tm[i][realIndex] !== -1) {
  5847. if (rows[i].cells[tm[i][realIndex]].colSpan > 1) {
  5848. rows[i].cells[tm[i][realIndex]].colSpan++;
  5849. } else {
  5850. newc = rows[i].insertCell(tm[i][realIndex] + 1);
  5851. nc = rows[i].cells[tm[i][realIndex]].cloneNode(false);
  5852. nc.innerHTML = '&nbsp;';
  5853. rows[i].replaceChild(nc, newc);
  5854. }
  5855. }
  5856. }
  5857. },
  5858. insertRow = function (idx) {
  5859. newr = ctb.insertRow(ctr.rowIndex + 1);
  5860. for (i = 0; i < ctr.cells.length; i++) {
  5861. if (ctr.cells[i].rowSpan > 1) {
  5862. ctr.cells[i].rowSpan++;
  5863. } else {
  5864. newc = ctr.cells[i].cloneNode(false);
  5865. newc.innerHTML = '&nbsp;';
  5866. newr.appendChild(newc);
  5867. }
  5868. }
  5869. for (i = 0; i < ctr.rowIndex; i++) {
  5870. if (ctb.rows && ctb.rows.length > 0) {
  5871. tempr = ctb.rows[i];
  5872. } else {
  5873. tempr = ctb.getElementsByTagName('tr')[i];
  5874. }
  5875. for (j = 0; j < tempr.cells.length; j++) {
  5876. if (tempr.cells[j].rowSpan > (ctr.rowIndex - i)) {
  5877. tempr.cells[j].rowSpan++;
  5878. }
  5879. }
  5880. }
  5881. },
  5882. deleteColumn = function () {
  5883. tm = getCellMatrix(ctb);
  5884. rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr');
  5885. rowIndex = 0; realIndex = 0;
  5886. if (ctr.rowIndex >= 0) {
  5887. rowIndex = ctr.rowIndex;
  5888. } else {
  5889. for (i = 0; i < rows.length; i++) {
  5890. if (rows[i] === ctr) {
  5891. rowIndex = i;
  5892. break;
  5893. }
  5894. }
  5895. }
  5896. if (tm[0].length <= 1) {
  5897. ctb.parentNode.removeChild(ctb);
  5898. } else {
  5899. for (j = 0; j < tm[rowIndex].length; j++) {
  5900. if (tm[rowIndex][j] === ctd.cellIndex) {
  5901. realIndex = j;
  5902. break;
  5903. }
  5904. }
  5905. for (i = 0; i < rows.length; i++) {
  5906. if (tm[i][realIndex] !== -1) {
  5907. if (rows[i].cells[tm[i][realIndex]].colSpan > 1) {
  5908. rows[i].cells[tm[i][realIndex]].colSpan--;
  5909. } else {
  5910. rows[i].deleteCell(tm[i][realIndex]);
  5911. }
  5912. }
  5913. }
  5914. }
  5915. },
  5916. deleteRow = function () {
  5917. var curCI = -1, prevCI, ni, nrCI, cs, nj;
  5918. tm = getCellMatrix(ctb);
  5919. rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR');
  5920. rowIndex = 0;
  5921. if (ctr.rowIndex >= 0) {
  5922. rowIndex = ctr.rowIndex;
  5923. } else {
  5924. for (i = 0; i < rows.length; i++) {
  5925. if (rows[i] === ctr) {
  5926. rowIndex = i;
  5927. break;
  5928. }
  5929. }
  5930. }
  5931. if (rows.length <= 1) {
  5932. ctb.parentNode.removeChild(ctb);
  5933. } else {
  5934. for (i = 0; i < rowIndex; i++) {
  5935. tempr = rows[i];
  5936. for (j = 0; j < tempr.cells.length; j++) {
  5937. if (tempr.cells[j].rowSpan > (rowIndex - i)) {
  5938. tempr.cells[j].rowSpan--;
  5939. }
  5940. }
  5941. }
  5942. for (i = 0; i < tm[rowIndex].length; i++) {
  5943. prevCI = curCI;
  5944. curCI = tm[rowIndex][i];
  5945. if (curCI !== -1 && curCI !== prevCI && ctr.cells[curCI].rowSpan > 1 && (rowIndex + 1) < rows.length) {
  5946. ni = i;
  5947. nrCI = tm[rowIndex + 1][ni];
  5948. while (nrCI === -1) {
  5949. ni++;
  5950. nrCI = (ni < rows[rowIndex + 1].cells.length) ? tm[rowIndex + 1][ni] : rows[rowIndex + 1].cells.length;
  5951. }
  5952. newc = rows[rowIndex + 1].insertCell(nrCI);
  5953. rows[rowIndex].cells[curCI].rowSpan--;
  5954. nc = rows[rowIndex].cells[curCI].cloneNode(false);
  5955. rows[rowIndex + 1].replaceChild(nc, newc);
  5956. cs = (ctr.cells[curCI].colSpan > 1) ? ctr.cells[curCI].colSpan : 1;
  5957. nj = 0;
  5958. for (j = i; j < (i + cs) ; j++) {
  5959. tm[rowIndex + 1][j] = nrCI;
  5960. nj = j;
  5961. }
  5962. for (j = nj; j < tm[rowIndex + 1].length; j++) {
  5963. if (tm[rowIndex + 1][j] !== -1) {
  5964. tm[rowIndex + 1][j]++;
  5965. }
  5966. }
  5967. }
  5968. }
  5969. if (ctb.rows && ctb.rows.length > 0) {
  5970. ctb.deleteRow(rowIndex);
  5971. } else {
  5972. ctb.removeChild(rows[rowIndex]);
  5973. }
  5974. }
  5975. },
  5976. mergeCellRight = function () {
  5977. tm = getCellMatrix(ctb);
  5978. rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr');
  5979. rowIndex = 0; realIndex = 0;
  5980. if (ctr.rowIndex >= 0) {
  5981. rowIndex = ctr.rowIndex;
  5982. } else {
  5983. for (i = 0; i < rows.length; i++) {
  5984. if (rows[i] === ctr) {
  5985. rowIndex = i;
  5986. break;
  5987. }
  5988. }
  5989. }
  5990. for (j = 0; j < tm[rowIndex].length; j++) {
  5991. if (tm[rowIndex][j] === ctd.cellIndex) {
  5992. realIndex = j;
  5993. break;
  5994. }
  5995. }
  5996. if (ctd.cellIndex + 1 < ctr.cells.length) {
  5997. var ccrs = ctd.rowSpan || 1,
  5998. cccs = ctd.colSpan || 1,
  5999. ncrs = ctr.cells[ctd.cellIndex + 1].rowSpan || 1,
  6000. nccs = ctr.cells[ctd.cellIndex + 1].colSpan || 1,
  6001. html;
  6002. j = realIndex;
  6003. while (tm[rowIndex][j] === ctd.cellIndex) {
  6004. j++;
  6005. }
  6006. if (tm[rowIndex][j] === ctd.cellIndex + 1) {
  6007. if (ccrs === ncrs) {
  6008. if (rows.length > 1) {
  6009. ctd.colSpan = cccs + nccs;
  6010. }
  6011. html = self.trimSpace(ctr.cells[ctd.cellIndex + 1].innerHTML);
  6012. html = html.replace(/^&nbsp;/, '');
  6013. ctd.innerHTML += html;
  6014. ctr.deleteCell(ctd.cellIndex + 1);
  6015. }
  6016. }
  6017. }
  6018. },
  6019. mergeCellDown = function () {
  6020. var crealIndex = 0,
  6021. ccrs = ctd.rowSpan || 1,
  6022. cccs = ctd.colSpan || 1,
  6023. ncellIndex, html, ncrs, nccs;
  6024. tm = getCellMatrix(ctb);
  6025. rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr');
  6026. rowIndex = 0;
  6027. if (ctr.rowIndex >= 0) {
  6028. rowIndex = ctr.rowIndex;
  6029. } else {
  6030. for (i = 0; i < rows.length; i++) {
  6031. if (rows[i] === ctr) {
  6032. rowIndex = i;
  6033. break;
  6034. }
  6035. }
  6036. }
  6037. for (i = 0; i < tm[rowIndex].length; i++) {
  6038. if (tm[rowIndex][i] === ctd.cellIndex) {
  6039. crealIndex = i;
  6040. break;
  6041. }
  6042. }
  6043. if (rowIndex + ccrs < rows.length) {
  6044. ncellIndex = tm[rowIndex + ccrs][crealIndex];
  6045. if (ncellIndex !== -1 &&
  6046. (crealIndex === 0 || (crealIndex > 0 &&
  6047. (tm[rowIndex + ccrs][crealIndex - 1] !== tm[rowIndex + ccrs][crealIndex])))) {
  6048. ncrs = rows[rowIndex + ccrs].cells[ncellIndex].rowSpan || 1;
  6049. nccs = rows[rowIndex + ccrs].cells[ncellIndex].colSpan || 1;
  6050. if (cccs === nccs) {
  6051. html = self.trimSpace(rows[rowIndex + ccrs].cells[ncellIndex].innerHTML);
  6052. html = html.replace(/^&nbsp;/, '');
  6053. ctd.innerHTML += html;
  6054. rows[rowIndex + ccrs].deleteCell(ncellIndex);
  6055. ctd.rowSpan = ccrs + ncrs;
  6056. }
  6057. }
  6058. }
  6059. },
  6060. splitCellVertical = function () {
  6061. var ri, cs;
  6062. tm = getCellMatrix();
  6063. rowIndex = 0; realIndex = 0;
  6064. rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR');
  6065. if (ctr.rowIndex >= 0) {
  6066. rowIndex = ctr.rowIndex;
  6067. } else {
  6068. for (ri = 0; ri < rows.length; ri++) {
  6069. if (rows[ri] === ctr) {
  6070. rowIndex = ri;
  6071. break;
  6072. }
  6073. }
  6074. }
  6075. for (j = 0; j < tm[rowIndex].length; j++) {
  6076. if (tm[rowIndex][j] === ctd.cellIndex) {
  6077. realIndex = j;
  6078. break;
  6079. }
  6080. }
  6081. if (ctd.colSpan > 1) {
  6082. newc = rows[rowIndex].insertCell(ctd.cellIndex + 1);
  6083. ctd.colSpan--;
  6084. nc = ctd.cloneNode(false);
  6085. nc.innerHTML = '&nbsp;';
  6086. rows[rowIndex].replaceChild(nc, newc);
  6087. ctd.colSpan = 1;
  6088. ctd.removeAttribute('colSpan');
  6089. } else {
  6090. newc = rows[rowIndex].insertCell(ctd.cellIndex + 1);
  6091. nc = ctd.cloneNode(false);
  6092. nc.innerHTML = '&nbsp;';
  6093. rows[rowIndex].replaceChild(nc, newc);
  6094. for (i = 0; i < tm.length; i++) {
  6095. if (i !== rowIndex && tm[i][realIndex] !== -1) {
  6096. cs = (rows[i].cells[tm[i][realIndex]].colSpan > 1) ? rows[i].cells[tm[i][realIndex]].colSpan : 1;
  6097. rows[i].cells[tm[i][realIndex]].colSpan = cs + 1;
  6098. }
  6099. }
  6100. }
  6101. },
  6102. splitCellHorizontal = function () {
  6103. var ni, rs;
  6104. tm = getCellMatrix();
  6105. rowIndex = 0; realIndex = 0;
  6106. rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR');
  6107. if (ctr.rowIndex >= 0) {
  6108. rowIndex = ctr.rowIndex;
  6109. } else {
  6110. for (i = 0; i < rows.length; i++) {
  6111. if (rows[i] === ctr) {
  6112. rowIndex = i;
  6113. break;
  6114. }
  6115. }
  6116. }
  6117. for (j = 0; j < tm[rowIndex].length; j++) {
  6118. if (tm[rowIndex][j] === ctd.cellIndex) {
  6119. realIndex = j;
  6120. break;
  6121. }
  6122. }
  6123. if (ctd.rowSpan > 1) {
  6124. i = realIndex;
  6125. while (tm[rowIndex + 1][i] === -1) {
  6126. i++;
  6127. }
  6128. ni = (i === tm[rowIndex + 1].length) ? rows[rowIndex + 1].cells.length : tm[rowIndex + 1][i];
  6129. newc = rows[rowIndex + 1].insertCell(ni);
  6130. ctd.rowSpan--;
  6131. nc = ctd.cloneNode(false);
  6132. nc.innerHTML = '&nbsp;';
  6133. rows[rowIndex + 1].replaceChild(nc, newc);
  6134. ctd.rowSpan = 1;
  6135. } else {
  6136. if (ctb.rows && ctb.rows.length > 0) {
  6137. ctb.insertRow(rowIndex + 1);
  6138. } else {
  6139. if (rowIndex < (rows.length - 1)) {
  6140. ctb.insertBefore(document.createElement('TR'), rows[rowIndex + 1]);
  6141. } else {
  6142. ctb.appendChild(document.createElement('TR'));
  6143. }
  6144. }
  6145. for (i = 0; i < ctr.cells.length; i++) {
  6146. if (i !== ctd.cellIndex) {
  6147. rs = ctr.cells[i].rowSpan > 1 ? ctr.cells[i].rowSpan : 1;
  6148. ctr.cells[i].rowSpan = rs + 1;
  6149. }
  6150. }
  6151. for (i = 0; i < rowIndex; i++) {
  6152. tempr = rows[i];
  6153. for (j = 0; j < tempr.cells.length; j++) {
  6154. if (tempr.cells[j].rowSpan > (rowIndex - i)) {
  6155. tempr.cells[j].rowSpan++;
  6156. }
  6157. }
  6158. }
  6159. newc = rows[rowIndex + 1].insertCell(0);
  6160. nc = ctd.cloneNode(false);
  6161. nc.innerHTML = '&nbsp;';
  6162. rows[rowIndex + 1].replaceChild(nc, newc);
  6163. }
  6164. },
  6165. tblReflash = function () {
  6166. self.editAreaFocus(); self.doEditorEvent();
  6167. },
  6168. colorPickerEventHandler = function () {
  6169. GB.popupWindow.ColorPicker.argv = {
  6170. func: function (color) {
  6171. ctd.setAttribute('bgColor', color);
  6172. document.getElementById('fm_cell_bgcolor').value = color;
  6173. },
  6174. selectedCell: ctd
  6175. };
  6176. self.windowOpen('ColorPicker');
  6177. },
  6178. editSubmitEventHandler = function () {
  6179. var width = self.trimSpace(document.getElementById('fm_cell_width').value),
  6180. height = self.trimSpace(document.getElementById('fm_cell_height').value),
  6181. bgcolor = self.trimSpace(document.getElementById('fm_cell_bgcolor').value);
  6182. if (width) {
  6183. ctd.setAttribute('width', width);
  6184. }
  6185. if (height) {
  6186. ctd.setAttribute('height', height);
  6187. }
  6188. if (bgcolor) {
  6189. ctd.setAttribute('bgcolor', bgcolor);
  6190. }
  6191. },
  6192. deleteSubmitEventHandler = function () {
  6193. ctb.parentNode.removeChild(ctb);
  6194. self.doEditorEvent();
  6195. },
  6196. funcs = {
  6197. add_cols_after: {
  6198. icon: 'table_insert_column.png', title: '열 삽입',
  6199. func: function () {
  6200. insertColumn(ctd.cellIndex); tblReflash();
  6201. }
  6202. },
  6203. add_rows_after: {
  6204. icon: 'table_insert_row.png', title: '행 삽입',
  6205. func: function () {
  6206. insertRow(ctr.rowIndex); tblReflash();
  6207. }
  6208. },
  6209. remove_cols: {
  6210. icon: 'table_delete_column.png', title: '열 삭제',
  6211. func: function () {
  6212. deleteColumn(ctd.cellIndex); tblReflash();
  6213. }
  6214. },
  6215. remove_rows: {
  6216. icon: 'table_delete_row.png', title: '행 삭제',
  6217. func: function () {
  6218. deleteRow(); tblReflash();
  6219. }
  6220. },
  6221. sp1: { icon: 'dot.gif' },
  6222. merge_cell_right: {
  6223. icon: 'table_join_row.png', title: '오른쪽 셀과 병합',
  6224. func: function () {
  6225. mergeCellRight(); tblReflash();
  6226. }
  6227. },
  6228. merge_cell_down: {
  6229. icon: 'table_join_column.png', title: '아래 셀과 병합',
  6230. func: function () {
  6231. mergeCellDown(); tblReflash();
  6232. }
  6233. },
  6234. split_cell_v: {
  6235. icon: 'table_split_row.png', title: '셀 열로 나누기',
  6236. func: function () {
  6237. splitCellVertical(); tblReflash();
  6238. }
  6239. },
  6240. split_cell_h: {
  6241. icon: 'table_split_column.png', title: '셀 행으로 나누기',
  6242. func: function () {
  6243. splitCellHorizontal(); tblReflash();
  6244. }
  6245. }
  6246. },
  6247. attrFuncs = {
  6248. setWidth: {
  6249. txt: '가로폭',
  6250. id: 'fm_cell_width',
  6251. marginRight: '10px',
  6252. value: ctd.getAttribute('width')
  6253. },
  6254. setHeight: {
  6255. txt: '세로폭',
  6256. id: 'fm_cell_height',
  6257. marginRight: '10px',
  6258. value: ctd.getAttribute('height')
  6259. },
  6260. setBgcolor: {
  6261. txt: '배경색',
  6262. id: 'fm_cell_bgcolor',
  6263. marginRight: '2px',
  6264. value: ctd.getAttribute('bgcolor')
  6265. }
  6266. },
  6267. deleteSubmit = new Image(),
  6268. spliter = document.createElement('div'), txt, input,
  6269. colorPicker = new Image(),
  6270. editSubmit = new Image();
  6271. while (ctb && ctb.tagName.toLowerCase() !== 'table') {
  6272. ctb = ctb.parentNode;
  6273. }
  6274. while (ctr && ctr.tagName.toLowerCase() !== 'tr') {
  6275. ctr = ctr.parentNode;
  6276. }
  6277. self.cheditor.editBlock.innerHTML = '';
  6278. div.style.padding = '6px';
  6279. for (i in funcs) {
  6280. if (!funcs.hasOwnProperty(i)) {
  6281. continue;
  6282. }
  6283. span = document.createElement('span');
  6284. icon = document.createElement('img');
  6285. icon.src = self.config.iconPath + funcs[i].icon;
  6286. if (i === 'sp1' || i === 'sp2') {
  6287. icon.className = 'edit-table-ico';
  6288. } else {
  6289. icon.setAttribute('title', funcs[i].title);
  6290. icon.className = 'edit-table-ico';
  6291. icon.setAttribute('alt', '');
  6292. icon.onclick = funcs[i].func;
  6293. }
  6294. div.appendChild(span.appendChild(icon));
  6295. }
  6296. deleteSubmit.src = this.config.iconPath + 'delete_table.png';
  6297. deleteSubmit.style.marginLeft = '22px';
  6298. deleteSubmit.className = 'edit-table-ico';
  6299. deleteSubmit.setAttribute('title', '테이블 삭제');
  6300. deleteSubmit.onclick = deleteSubmitEventHandler;
  6301. div.appendChild(deleteSubmit);
  6302. spliter.style.padding = '10px 0px 0px 0px';
  6303. spliter.style.marginTop = '5px';
  6304. spliter.style.borderTop = '1px solid #ccc';
  6305. spliter.style.textAlign = 'center';
  6306. for (i in attrFuncs) {
  6307. if (!attrFuncs.hasOwnProperty(i)) {
  6308. continue;
  6309. }
  6310. txt = document.createTextNode(attrFuncs[i].txt + ' ');
  6311. spliter.appendChild(txt);
  6312. input = document.createElement('input');
  6313. input.style.marginRight = attrFuncs[i].marginRight;
  6314. input.setAttribute('type', 'text');
  6315. input.setAttribute('name', i);
  6316. input.setAttribute('id', attrFuncs[i].id);
  6317. input.setAttribute('size', 7);
  6318. input.setAttribute('value', attrFuncs[i].value || '');
  6319. spliter.appendChild(input);
  6320. }
  6321. colorPicker.src = this.config.iconPath + 'button/color_picker.gif';
  6322. colorPicker.className = 'color-picker';
  6323. colorPicker.onclick = colorPickerEventHandler;
  6324. spliter.appendChild(colorPicker);
  6325. editSubmit.src = this.config.iconPath + 'button/edit_cell.gif';
  6326. editSubmit.className = 'input-submit';
  6327. editSubmit.style.verticalAlign = 'top';
  6328. editSubmit.onclick = editSubmitEventHandler;
  6329. spliter.appendChild(editSubmit);
  6330. div.appendChild(spliter);
  6331. self.cheditor.editBlock.appendChild(div);
  6332. },
  6333. doEditorEvent: function (evt) {
  6334. var self = this,
  6335. cmd = null, ancestors = [], node, el, pNode, range, sType, links, span, tag, remove, bText,
  6336. srcElement = evt.target || evt.srcElement,
  6337. block = self.cheditor.editBlock,
  6338. status = self.cheditor.tagPath,
  6339. linkOnClickEventHandler = function () {
  6340. if (bText) {
  6341. document.getElementById('removeSelected').style.display = 'inline';
  6342. self.tagSelector(this.el);
  6343. }
  6344. },
  6345. removeOnClickEventHandler = function () {
  6346. self.doc.execCommand('RemoveFormat', false, null);
  6347. remove.style.display = 'none';
  6348. self.editAreaFocus();
  6349. self.doEditorEvent();
  6350. };
  6351. if (!this.undefined(srcElement) && srcElement.nodeType === GB.node.element) {
  6352. pNode = srcElement;
  6353. } else {
  6354. range = self.getRange();
  6355. sType = self.getSelectionType();
  6356. bText = sType === GB.selection.text;
  6357. if (!self.W3CRange) {
  6358. switch (sType) {
  6359. case GB.selection.none:
  6360. case GB.selection.text:
  6361. pNode = range.parentElement();
  6362. break;
  6363. case GB.selection.element:
  6364. pNode = range.item(0);
  6365. break;
  6366. default:
  6367. pNode = self.editArea.document.body;
  6368. }
  6369. } else {
  6370. pNode = range.commonAncestorContainer;
  6371. if (!range.collapsed &&
  6372. range.startContainer === range.endContainer &&
  6373. range.startOffset - range.endOffset < 2 &&
  6374. range.startContainer.hasChildNodes()) {
  6375. pNode = range.startContainer.childNodes[range.startOffset];
  6376. }
  6377. while (pNode.nodeType === GB.node.text) {
  6378. pNode = pNode.parentNode;
  6379. }
  6380. }
  6381. }
  6382. node = pNode;
  6383. while (pNode && pNode.nodeType === GB.node.element) {
  6384. if (pNode.tagName.toLowerCase() === 'body') {
  6385. break;
  6386. }
  6387. if (pNode.tagName.toLowerCase() === 'img') {
  6388. cmd = 'img'; break;
  6389. }
  6390. if (pNode.tagName.toLowerCase() === 'td' || pNode.tagName.toLowerCase() === 'th') {
  6391. cmd = 'cell'; break;
  6392. }
  6393. pNode = pNode.parentNode;
  6394. }
  6395. if (!cmd) {
  6396. block.style.display = 'none';
  6397. block.innerHTML = '';
  6398. } else {
  6399. if (cmd === 'cell') {
  6400. block.style.display = 'block';
  6401. self.modifyCell(pNode);
  6402. }
  6403. }
  6404. if (self.config.showTagPath) {
  6405. while (node && node.nodeType === GB.node.element) {
  6406. ancestors.push(node);
  6407. if (node.tagName.toLowerCase() === 'body') {
  6408. break;
  6409. }
  6410. node = node.parentNode;
  6411. }
  6412. status.innerHTML = '';
  6413. status.appendChild(document.createTextNode('<html> '));
  6414. el = ancestors.pop();
  6415. while (el) {
  6416. status.appendChild(document.createTextNode('<'));
  6417. tag = el.nodeName.toLowerCase();
  6418. links = document.createElement('a');
  6419. links.el = el;
  6420. links.href = 'javascript:void%200';
  6421. links.className = 'cheditor-tag-path-elem';
  6422. links.title = el.style.cssText;
  6423. (function () {
  6424. links.onclick = linkOnClickEventHandler;
  6425. })();
  6426. links.appendChild(document.createTextNode(tag));
  6427. status.appendChild(links);
  6428. status.appendChild(document.createTextNode('> '));
  6429. el = ancestors.pop();
  6430. }
  6431. if (bText) {
  6432. remove = document.createElement('a');
  6433. remove.href = 'javascript:void%200';
  6434. remove.id = 'removeSelected';
  6435. remove.style.display = 'none';
  6436. remove.className = 'cheditor-tag-path-elem';
  6437. remove.style.color = '#cc3300';
  6438. remove.appendChild(document.createTextNode('<remove format>'));
  6439. (function () {
  6440. remove.onclick = removeOnClickEventHandler;
  6441. })();
  6442. span = document.createElement('span');
  6443. span.style.marginTop = '2px';
  6444. span.appendChild(remove);
  6445. self.cheditor.tagPath.appendChild(span);
  6446. }
  6447. }
  6448. self.toolbarUpdate(srcElement);
  6449. },
  6450. tagSelector: function (node) {
  6451. var rng, selection;
  6452. this.editAreaFocus();
  6453. if (this.W3CRange) {
  6454. selection = this.editArea.getSelection();
  6455. if (this.undefined(selection)) {
  6456. return;
  6457. }
  6458. try {
  6459. rng = selection.getRangeAt(0);
  6460. } catch (e) {
  6461. return;
  6462. }
  6463. rng.selectNodeContents(node);
  6464. selection.removeAllRanges();
  6465. selection.addRange(rng);
  6466. } else {
  6467. rng = this.doc.body.createTextRange();
  6468. if (rng) {
  6469. rng.moveToElementText(node);
  6470. rng.select();
  6471. }
  6472. }
  6473. },
  6474. getBrowser: function () {
  6475. return GB.browser;
  6476. },
  6477. $: function (id) {
  6478. return this.doc.getElementById(id);
  6479. }
  6480. };
  6481. (function () {
  6482. var dragWindow = {
  6483. obj: null,
  6484. init: function (o, oRoot, minX, maxX, minY, maxY) {
  6485. o.style.curser = 'default';
  6486. o.onmousedown = dragWindow.start;
  6487. o.onmouseover = function () {
  6488. this.style.cursor = 'move';
  6489. };
  6490. o.hmode = true;
  6491. o.vmode = true;
  6492. o.root = (oRoot && oRoot !== null) ? oRoot : o;
  6493. o.transId = oRoot.id + '_Trans';
  6494. if (o.hmode && isNaN(parseInt(o.root.style.left, 10))) {
  6495. o.root.style.left = '0px';
  6496. }
  6497. if (o.vmode && isNaN(parseInt(o.root.style.top, 10))) {
  6498. o.root.style.top = '0px';
  6499. }
  6500. if (!o.hmode && isNaN(parseInt(o.root.style.right, 10))) {
  6501. o.root.style.right = '0px';
  6502. }
  6503. if (!o.vmode && isNaN(parseInt(o.root.style.bottom, 10))) {
  6504. o.root.style.bottom = '0px';
  6505. }
  6506. o.minX = minX !== undefined ? minX : null;
  6507. o.minY = minY !== undefined ? minY : null;
  6508. o.maxX = maxX !== undefined ? maxX : null;
  6509. o.maxY = maxY !== undefined ? maxY : null;
  6510. o.root.onDragStart = new Function();
  6511. o.root.onDragEnd = new Function();
  6512. o.root.onDrag = new Function();
  6513. },
  6514. start: function (e) {
  6515. var o = dragWindow.obj = this,
  6516. dragTransBg = document.createElement('div'),
  6517. y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10),
  6518. x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10);
  6519. e = dragWindow.fixEv(e);
  6520. o.root.onDragStart(x, y);
  6521. o.lastMouseX = e.clientX;
  6522. o.lastMouseY = e.clientY;
  6523. document.onmousemove = dragWindow.drag;
  6524. document.onmouseup = dragWindow.end;
  6525. if (o.root.lastChild.id === o.transId) {
  6526. return false;
  6527. }
  6528. dragTransBg.className = 'cheditor-dragWindowTransparent';
  6529. if (GB.browser.msie && GB.browser.version < 10) {
  6530. dragTransBg.style.filter = 'alpha(opacity=0)';
  6531. } else {
  6532. dragTransBg.style.opacity = 0;
  6533. }
  6534. dragTransBg.id = o.transId;
  6535. dragTransBg.style.width = o.root.lastChild.firstChild.style.width;
  6536. dragTransBg.style.height = o.root.lastChild.firstChild.style.height;
  6537. o.root.appendChild(dragTransBg);
  6538. return false;
  6539. },
  6540. drag: function (e) {
  6541. e = dragWindow.fixEv(e);
  6542. var o = dragWindow.obj,
  6543. ey = e.clientY,
  6544. ex = e.clientX,
  6545. y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10),
  6546. x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10),
  6547. nx, ny;
  6548. nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
  6549. ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));
  6550. dragWindow.obj.root.style.left = nx + 'px';
  6551. dragWindow.obj.root.style.top = ny + 'px';
  6552. dragWindow.obj.lastMouseX = ex;
  6553. dragWindow.obj.lastMouseY = ey;
  6554. dragWindow.obj.root.onDrag(nx, ny);
  6555. return false;
  6556. },
  6557. end: function () {
  6558. document.onmousemove = null;
  6559. document.onmouseup = null;
  6560. dragWindow.obj.root.onDragEnd(parseInt(dragWindow.obj.root.style[dragWindow.obj.hmode ? 'left' : 'right'], 10),
  6561. parseInt(dragWindow.obj.root.style[dragWindow.obj.vmode ? 'top' : 'bottom'], 10));
  6562. if (dragWindow.obj.root.lastChild.id === dragWindow.obj.transId) {
  6563. dragWindow.obj.root.removeChild(dragWindow.obj.root.lastChild);
  6564. }
  6565. dragWindow.obj = null;
  6566. },
  6567. fixEv: function (e) {
  6568. if (e === undefined) {
  6569. e = window.event;
  6570. }
  6571. if (e.layerX === undefined) {
  6572. e.layerX = e.offsetX;
  6573. }
  6574. if (e.layerY === undefined) {
  6575. e.layerY = e.offsetY;
  6576. }
  6577. return e;
  6578. }
  6579. };
  6580. GB.dragWindow = dragWindow;
  6581. })();
  6582. // --------------------------------------------------------------------------
  6583. // W3C DOM Range
  6584. //
  6585. // --------------------------------------------------------------------------
  6586. // Table
  6587. //
  6588. // --------------------------------------------------------------------------
  6589. // Color Picker
  6590. //
  6591. (function () {
  6592. var colorDropper = {
  6593. images: { pad: [181, 101], sld: [16, 101], cross: [15, 15], arrow: [7, 11] },
  6594. fetchElement: function (mixed) {
  6595. return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;
  6596. },
  6597. addEvent: function (el, evnt, func) {
  6598. if (el.addEventListener) {
  6599. el.addEventListener(evnt, func, false);
  6600. } else if (el.attachEvent) {
  6601. el.attachEvent('on' + evnt, func);
  6602. }
  6603. },
  6604. fireEvent: function (el, evnt) {
  6605. if (!el) {
  6606. return;
  6607. }
  6608. var ev;
  6609. if (document.createEvent) {
  6610. ev = document.createEvent('HTMLEvents');
  6611. ev.initEvent(evnt, true, true);
  6612. el.dispatchEvent(ev);
  6613. } else if (document.createEventObject) {
  6614. ev = document.createEventObject();
  6615. el.fireEvent('on' + evnt, ev);
  6616. } else if (el['on' + evnt]) {
  6617. el['on' + evnt]();
  6618. }
  6619. },
  6620. getElementPos: function (e) {
  6621. var e1 = e, e2 = e, x = 0, y = 0;
  6622. if (e1.offsetParent) {
  6623. do {
  6624. x += e1.offsetLeft;
  6625. y += e1.offsetTop;
  6626. e1 = e1.offsetParent;
  6627. } while (e1);
  6628. }
  6629. while (e2 && e2.nodeName.toLowerCase() !== 'body') {
  6630. x -= e2.scrollLeft;
  6631. y -= e2.scrollTop;
  6632. e2 = e2.parentNode;
  6633. }
  6634. return [x, y];
  6635. },
  6636. getElementSize: function (e) {
  6637. return [e.offsetWidth, e.offsetHeight];
  6638. },
  6639. getRelMousePos: function (e) {
  6640. var x = 0, y = 0;
  6641. if (!e) {
  6642. e = window.event;
  6643. }
  6644. if (typeof e.offsetX === 'number') {
  6645. x = e.offsetX;
  6646. y = e.offsetY;
  6647. } else if (typeof e.layerX === 'number') {
  6648. x = e.layerX;
  6649. y = e.layerY;
  6650. }
  6651. return { x: x, y: y };
  6652. },
  6653. color: function (target, prop) {
  6654. this.required = true;
  6655. this.adjust = true;
  6656. this.hash = true;
  6657. this.caps = false;
  6658. this.valueElement = target;
  6659. this.styleElement = target;
  6660. this.onImmediateChange = null;
  6661. this.hsv = [0, 0, 1];
  6662. this.rgb = [1, 1, 1];
  6663. this.minH = 0;
  6664. this.maxH = 6;
  6665. this.minS = 0;
  6666. this.maxS = 1;
  6667. this.minV = 0;
  6668. this.maxV = 1;
  6669. this.pickerOnfocus = true;
  6670. this.pickerMode = 'HSV';
  6671. this.pickerFace = 3;
  6672. this.pickerFaceColor = '#fff';
  6673. this.pickerInset = 1;
  6674. this.pickerInsetColor = '#999';
  6675. this.pickerZIndex = 10003;
  6676. var p,
  6677. self = this,
  6678. modeID = this.pickerMode.toLowerCase() === 'hvs' ? 1 : 0,
  6679. abortBlur = false,
  6680. valueElement = colorDropper.fetchElement(this.valueElement), styleElement = colorDropper.fetchElement(this.styleElement),
  6681. holdPad = false, holdSld = false, touchOffset = {},
  6682. leaveValue = 1 << 0, leaveStyle = 1 << 1, leavePad = 1 << 2, leaveSld = 1 << 3,
  6683. updateFieldEventHandler = function () {
  6684. self.fromString(valueElement.value, leaveValue);
  6685. dispatchImmediateChange();
  6686. };
  6687. colorDropper.addEvent(target, 'blur', function () {
  6688. if (!abortBlur) {
  6689. window.setTimeout(function () {
  6690. abortBlur || blurTarget();
  6691. abortBlur = false;
  6692. }, 0);
  6693. } else {
  6694. abortBlur = false;
  6695. }
  6696. });
  6697. for (p in prop) {
  6698. if (prop.hasOwnProperty(p)) {
  6699. this[p] = prop[p];
  6700. }
  6701. }
  6702. this.hidePicker = function () {
  6703. if (isPickerOwner()) {
  6704. removePicker();
  6705. }
  6706. };
  6707. this.showPicker = function () {
  6708. if (!isPickerOwner()) {
  6709. drawPicker();
  6710. }
  6711. };
  6712. this.importColor = function () {
  6713. if (!valueElement) {
  6714. this.exportColor();
  6715. } else {
  6716. if (!this.adjust) {
  6717. if (!this.fromString(valueElement.value, leaveValue)) {
  6718. styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
  6719. styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
  6720. styleElement.style.color = styleElement.jscStyle.color;
  6721. this.exportColor(leaveValue | leaveStyle);
  6722. }
  6723. } else if (!this.required && /^\s*$/.test(valueElement.value)) {
  6724. valueElement.value = '';
  6725. styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
  6726. styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
  6727. styleElement.style.color = styleElement.jscStyle.color;
  6728. this.exportColor(leaveValue | leaveStyle);
  6729. } else if (this.fromString(valueElement.value)) {
  6730. // ignore
  6731. } else {
  6732. this.exportColor();
  6733. }
  6734. }
  6735. };
  6736. this.exportColor = function (flags) {
  6737. if (!(flags & leaveValue) && valueElement) {
  6738. var value = this.toString();
  6739. if (this.caps) {
  6740. value = value.toUpperCase();
  6741. }
  6742. if (this.hash) {
  6743. value = '#' + value;
  6744. }
  6745. valueElement.value = value;
  6746. }
  6747. if (!(flags & leaveStyle) && styleElement) {
  6748. styleElement.style.backgroundImage = 'none';
  6749. styleElement.style.backgroundColor = '#' + this.toString();
  6750. styleElement.style.color = 0.213 * this.rgb[0] + 0.715 * this.rgb[1] + 0.072 * this.rgb[2] < 0.5 ? '#FFF' : '#000';
  6751. }
  6752. if (!(flags & leavePad) && isPickerOwner()) {
  6753. redrawPad();
  6754. }
  6755. if (!(flags & leaveSld) && isPickerOwner()) {
  6756. redrawSld();
  6757. }
  6758. };
  6759. this.fromHSV = function (h, s, v, flags) {
  6760. if (h) {
  6761. h = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, h));
  6762. }
  6763. if (s) {
  6764. s = Math.max(0.0, this.minS, Math.min(1.0, this.maxS, s));
  6765. }
  6766. if (v) {
  6767. v = Math.max(0.0, this.minV, Math.min(1.0, this.maxV, v));
  6768. }
  6769. this.rgb = this.HSV_RGB(
  6770. h === null ? this.hsv[0] : (this.hsv[0] = h),
  6771. s === null ? this.hsv[1] : (this.hsv[1] = s),
  6772. v === null ? this.hsv[2] : (this.hsv[2] = v)
  6773. );
  6774. this.exportColor(flags);
  6775. };
  6776. this.fromRGB = function (r, g, b, flags) {
  6777. if (r) {
  6778. r = Math.max(0.0, Math.min(1.0, r));
  6779. }
  6780. if (g) {
  6781. g = Math.max(0.0, Math.min(1.0, g));
  6782. }
  6783. if (b) {
  6784. b = Math.max(0.0, Math.min(1.0, b));
  6785. }
  6786. var hsv = this.RGB_HSV(
  6787. r === null ? this.rgb[0] : r,
  6788. g === null ? this.rgb[1] : g,
  6789. b === null ? this.rgb[2] : b
  6790. );
  6791. if (hsv[0] !== null) {
  6792. this.hsv[0] = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, hsv[0]));
  6793. }
  6794. if (hsv[2] !== 0) {
  6795. this.hsv[1] = hsv[1] === null ? null : Math.max(0.0, this.minS, Math.min(1.0, this.maxS, hsv[1]));
  6796. }
  6797. this.hsv[2] = hsv[2] === null ? null : Math.max(0.0, this.minV, Math.min(1.0, this.maxV, hsv[2]));
  6798. var rgb = this.HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);
  6799. this.rgb[0] = rgb[0];
  6800. this.rgb[1] = rgb[1];
  6801. this.rgb[2] = rgb[2];
  6802. this.exportColor(flags);
  6803. };
  6804. this.fromString = function (hex, flags) {
  6805. var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
  6806. if (!m) {
  6807. return false;
  6808. }
  6809. if (m[1].length === 6) {
  6810. this.fromRGB(
  6811. parseInt(m[1].substr(0, 2), 16) / 255,
  6812. parseInt(m[1].substr(2, 2), 16) / 255,
  6813. parseInt(m[1].substr(4, 2), 16) / 255,
  6814. flags
  6815. );
  6816. } else {
  6817. this.fromRGB(
  6818. parseInt(m[1].charAt(0) + m[1].charAt(0), 16) / 255,
  6819. parseInt(m[1].charAt(1) + m[1].charAt(1), 16) / 255,
  6820. parseInt(m[1].charAt(2) + m[1].charAt(2), 16) / 255,
  6821. flags
  6822. );
  6823. }
  6824. return true;
  6825. };
  6826. this.toString = function () {
  6827. return (
  6828. (0x100 | Math.round(255 * this.rgb[0])).toString(16).substr(1) +
  6829. (0x100 | Math.round(255 * this.rgb[1])).toString(16).substr(1) +
  6830. (0x100 | Math.round(255 * this.rgb[2])).toString(16).substr(1)
  6831. );
  6832. };
  6833. this.RGB_HSV = function (r, g, b) {
  6834. var n = Math.min(Math.min(r, g), b),
  6835. v = Math.max(Math.max(r, g), b),
  6836. m = v - n, h;
  6837. if (m === 0) {
  6838. return [null, 0, v];
  6839. }
  6840. h = r === n ? 3 + (b - g) / m : (g === n ? 5 + (r - b) / m : 1 + (g - r) / m);
  6841. return [h === 6 ? 0 : h, m / v, v];
  6842. };
  6843. this.HSV_RGB = function (h, s, v) {
  6844. if (h === null) {
  6845. return [v, v, v];
  6846. }
  6847. var i = Math.floor(h),
  6848. f = i % 2 ? h - i : 1 - (h - i),
  6849. m = v * (1 - s),
  6850. n = v * (1 - s * f);
  6851. switch (i) {
  6852. case 6:
  6853. case 0:
  6854. return [v, n, m];
  6855. case 1:
  6856. return [n, v, m];
  6857. case 2:
  6858. return [m, v, n];
  6859. case 3:
  6860. return [m, n, v];
  6861. case 4:
  6862. return [n, m, v];
  6863. case 5:
  6864. return [v, m, n];
  6865. }
  6866. };
  6867. function removePicker() {
  6868. delete colorDropper.picker.owner;
  6869. colorDropper.picker.boxB.parentNode.removeChild(colorDropper.picker.boxB);
  6870. }
  6871. function drawPicker() {
  6872. var touchMoveEventHandler = function (e) {
  6873. var event = {
  6874. 'offsetX': e.touches[0].pageX - touchOffset.X,
  6875. 'offsetY': e.touches[0].pageY - touchOffset.Y
  6876. };
  6877. if (holdPad || holdSld) {
  6878. holdPad && setPad(event);
  6879. holdSld && setSld(event);
  6880. dispatchImmediateChange();
  6881. }
  6882. e.stopPropagation();
  6883. e.preventDefault();
  6884. },
  6885. dims = getPickerDims(self),
  6886. padImg = modeID ? 'color_picker_hv.png' : 'color_picker_hs.png',
  6887. i, seg, segSize;
  6888. if (!colorDropper.picker) {
  6889. colorDropper.picker = {
  6890. box: document.createElement('div'),
  6891. boxB: document.createElement('div'),
  6892. pad: document.createElement('div'),
  6893. padB: document.createElement('div'),
  6894. padM: document.createElement('div'),
  6895. sld: document.createElement('div'),
  6896. sldB: document.createElement('div'),
  6897. sldM: document.createElement('div')
  6898. };
  6899. for (i = 0, segSize = 2; i < colorDropper.images.sld[1]; i += segSize) {
  6900. seg = document.createElement('div');
  6901. seg.style.height = segSize + 'px';
  6902. seg.style.fontSize = '1px';
  6903. seg.style.lineHeight = '0px';
  6904. colorDropper.picker.sld.appendChild(seg);
  6905. }
  6906. colorDropper.picker.sldB.appendChild(colorDropper.picker.sld);
  6907. colorDropper.picker.box.appendChild(colorDropper.picker.sldB);
  6908. colorDropper.picker.box.appendChild(colorDropper.picker.sldM);
  6909. colorDropper.picker.padB.appendChild(colorDropper.picker.pad);
  6910. colorDropper.picker.box.appendChild(colorDropper.picker.padB);
  6911. colorDropper.picker.box.appendChild(colorDropper.picker.padM);
  6912. colorDropper.picker.boxB.appendChild(colorDropper.picker.box);
  6913. }
  6914. p = colorDropper.picker;
  6915. p.box.onmouseup = p.box.onmouseout = function () {
  6916. target.focus();
  6917. };
  6918. p.box.onmousedown = function () {
  6919. abortBlur = true;
  6920. };
  6921. p.box.onmousemove = function (e) {
  6922. if (holdPad || holdSld) {
  6923. holdPad && setPad(e);
  6924. holdSld && setSld(e);
  6925. if (document.selection) {
  6926. document.selection.empty();
  6927. } else if (window.getSelection) {
  6928. window.getSelection().removeAllRanges();
  6929. }
  6930. dispatchImmediateChange();
  6931. }
  6932. };
  6933. if ('ontouchstart' in window) {
  6934. p.box.removeEventListener('touchmove', touchMoveEventHandler, false);
  6935. p.box.addEventListener('touchmove', touchMoveEventHandler, false);
  6936. }
  6937. p.padM.onmouseup = p.padM.onmouseout = function () {
  6938. if (holdPad) {
  6939. holdPad = false;
  6940. colorDropper.fireEvent(valueElement, 'change');
  6941. }
  6942. };
  6943. p.padM.onmousedown = function (e) {
  6944. switch (modeID) {
  6945. case 0:
  6946. if (self.hsv[2] === 0) {
  6947. self.fromHSV(null, null, 1.0);
  6948. }
  6949. break;
  6950. case 1:
  6951. if (self.hsv[1] === 0) {
  6952. self.fromHSV(null, 1.0, null);
  6953. }
  6954. break;
  6955. }
  6956. holdSld = false;
  6957. holdPad = true;
  6958. setPad(e);
  6959. dispatchImmediateChange();
  6960. };
  6961. if ('ontouchstart' in window) {
  6962. p.padM.addEventListener('touchstart', function (e) {
  6963. touchOffset = { 'X': getOffsetParent(e.target).Left, 'Y': getOffsetParent(e.target).Top };
  6964. this.onmousedown({
  6965. 'offsetX': e.touches[0].pageX - touchOffset.X,
  6966. 'offsetY': e.touches[0].pageY - touchOffset.Y
  6967. });
  6968. });
  6969. }
  6970. p.sldM.onmouseup = p.sldM.onmouseout = function () {
  6971. if (holdSld) {
  6972. holdSld = false;
  6973. colorDropper.fireEvent(valueElement, 'change');
  6974. }
  6975. };
  6976. p.sldM.onmousedown = function (e) {
  6977. holdPad = false;
  6978. holdSld = true;
  6979. setSld(e);
  6980. dispatchImmediateChange();
  6981. };
  6982. if ('ontouchstart' in window) {
  6983. p.sldM.addEventListener('touchstart', function (e) {
  6984. touchOffset = { 'X': getOffsetParent(e.target).Left, 'Y': getOffsetParent(e.target).Top };
  6985. this.onmousedown({
  6986. 'offsetX': e.touches[0].pageX - touchOffset.X,
  6987. 'offsetY': e.touches[0].pageY - touchOffset.Y
  6988. });
  6989. });
  6990. }
  6991. p.box.style.width = dims[0] + 'px';
  6992. p.box.style.height = dims[1] + 'px';
  6993. p.boxB.style.position = 'relative';
  6994. p.boxB.style.clear = 'both';
  6995. p.boxB.style.border = 'none';
  6996. p.boxB.style.background = self.pickerFaceColor;
  6997. p.pad.style.width = colorDropper.images.pad[0] + 'px';
  6998. p.pad.style.height = colorDropper.images.pad[1] + 'px';
  6999. p.padB.style.position = 'absolute';
  7000. p.padB.style.left = self.pickerFace + 'px';
  7001. p.padB.style.top = self.pickerFace + 'px';
  7002. p.padB.style.border = self.pickerInset + 'px solid';
  7003. p.padB.style.borderColor = self.pickerInsetColor;
  7004. p.padM.style.position = 'absolute';
  7005. p.padM.style.left = '0';
  7006. p.padM.style.top = '0';
  7007. p.padM.style.width = self.pickerFace + 2 * self.pickerInset + colorDropper.images.pad[0] + colorDropper.images.arrow[0] + 'px';
  7008. p.padM.style.height = p.box.style.height;
  7009. p.padM.style.cursor = 'crosshair';
  7010. p.sld.style.overflow = 'hidden';
  7011. p.sld.style.width = '13px';
  7012. p.sld.style.height = colorDropper.images.sld[1] + 'px';
  7013. p.sldB.style.position = 'absolute';
  7014. p.sldB.style.right = self.pickerFace + 'px';
  7015. p.sldB.style.top = self.pickerFace + 'px';
  7016. p.sldB.style.border = self.pickerInset + 'px solid';
  7017. p.sldB.style.borderColor = self.pickerInsetColor;
  7018. p.sldM.style.position = 'absolute';
  7019. p.sldM.style.right = '0';
  7020. p.sldM.style.top = '0';
  7021. p.sldM.style.width = 14 + colorDropper.images.arrow[0] + self.pickerFace + 2 * self.pickerInset + 'px';
  7022. p.sldM.style.height = p.box.style.height;
  7023. try {
  7024. p.sldM.style.cursor = 'pointer';
  7025. } catch (e) {
  7026. p.sldM.style.cursor = 'hand';
  7027. }
  7028. p.padM.style.backgroundImage = 'url("' + self.iconDir + '/color_picker_cross.gif")';
  7029. p.padM.style.backgroundRepeat = 'no-repeat';
  7030. p.sldM.style.backgroundImage = 'url("' + self.iconDir + '/color_picker_arrow.gif")';
  7031. p.sldM.style.backgroundRepeat = 'no-repeat';
  7032. p.pad.style.backgroundImage = 'url("' + self.iconDir + '/' + padImg + '")';
  7033. p.pad.style.backgroundRepeat = 'no-repeat';
  7034. p.pad.style.backgroundPosition = '0 0';
  7035. redrawPad();
  7036. redrawSld();
  7037. colorDropper.picker.owner = self;
  7038. target.parentNode.parentNode.appendChild(p.boxB);
  7039. }
  7040. function getPickerDims(o) {
  7041. return [2 * o.pickerInset + 2 * o.pickerFace + colorDropper.images.pad[0] +
  7042. 2 * o.pickerInset + 2 * colorDropper.images.arrow[0] + colorDropper.images.sld[0],
  7043. 2 * o.pickerInset + 2 * o.pickerFace + colorDropper.images.pad[1]];
  7044. }
  7045. function redrawPad() {
  7046. var yComponent, x, y, i = 0, rgb, s, c, f,
  7047. seg = colorDropper.picker.sld.childNodes;
  7048. switch (modeID) {
  7049. case 0:
  7050. yComponent = 1;
  7051. break;
  7052. case 1:
  7053. yComponent = 2;
  7054. break;
  7055. }
  7056. x = Math.round((self.hsv[0] / 6) * (colorDropper.images.pad[0] - 1));
  7057. y = Math.round((1 - self.hsv[yComponent]) * (colorDropper.images.pad[1] - 1));
  7058. colorDropper.picker.padM.style.backgroundPosition =
  7059. (self.pickerFace + self.pickerInset + x - Math.floor(colorDropper.images.cross[0] / 2)) + 'px ' +
  7060. (self.pickerFace + self.pickerInset + y - Math.floor(colorDropper.images.cross[1] / 2)) + 'px';
  7061. switch (modeID) {
  7062. case 0:
  7063. rgb = self.HSV_RGB(self.hsv[0], self.hsv[1], 1);
  7064. if (window.File && window.FileReader) {
  7065. colorDropper.picker.sld.style.background = 'linear-gradient(rgb(' +
  7066. (rgb[0] * (1 - i / seg.length) * 100) + '%,' +
  7067. (rgb[1] * (1 - i / seg.length) * 100) + '%,' +
  7068. (rgb[2] * (1 - i / seg.length) * 100) + '%), black)';
  7069. } else {
  7070. for (i = 0; i < seg.length; i += 1) {
  7071. seg[i].style.backgroundColor = 'rgb(' +
  7072. (rgb[0] * (1 - i / seg.length) * 100) + '%,' +
  7073. (rgb[1] * (1 - i / seg.length) * 100) + '%,' +
  7074. (rgb[2] * (1 - i / seg.length) * 100) + '%)';
  7075. }
  7076. }
  7077. break;
  7078. case 1:
  7079. c = [self.hsv[2], 0, 0];
  7080. i = Math.floor(self.hsv[0]);
  7081. f = i % 2 ? self.hsv[0] - i : 1 - (self.hsv[0] - i);
  7082. switch (i) {
  7083. case 6:
  7084. case 0:
  7085. rgb = [0, 1, 2];
  7086. break;
  7087. case 1:
  7088. rgb = [1, 0, 2];
  7089. break;
  7090. case 2:
  7091. rgb = [2, 0, 1];
  7092. break;
  7093. case 3:
  7094. rgb = [2, 1, 0];
  7095. break;
  7096. case 4:
  7097. rgb = [1, 2, 0];
  7098. break;
  7099. case 5:
  7100. rgb = [0, 2, 1];
  7101. break;
  7102. }
  7103. for (i = 0; i < seg.length; i += 1) {
  7104. s = 1 - 1 / (seg.length - 1) * i;
  7105. c[1] = c[0] * (1 - s * f);
  7106. c[2] = c[0] * (1 - s);
  7107. seg[i].style.backgroundColor = 'rgb(' +
  7108. (c[rgb[0]] * 100) + '%,' +
  7109. (c[rgb[1]] * 100) + '%,' +
  7110. (c[rgb[2]] * 100) + '%)';
  7111. }
  7112. break;
  7113. }
  7114. }
  7115. function getOffsetParent(el) {
  7116. var parent = el.offsetParent, top = 0, left = 0;
  7117. while (parent) {
  7118. top += parent.offsetTop;
  7119. left += parent.offsetLeft;
  7120. parent = parent.offsetParent;
  7121. }
  7122. return { Left: left, Top: top };
  7123. }
  7124. function redrawSld() {
  7125. var yComponent, y;
  7126. switch (modeID) {
  7127. case 0:
  7128. yComponent = 2;
  7129. break;
  7130. case 1:
  7131. yComponent = 1;
  7132. break;
  7133. }
  7134. y = Math.round((1 - self.hsv[yComponent]) * (colorDropper.images.sld[1] - 1));
  7135. colorDropper.picker.sldM.style.backgroundPosition =
  7136. '0 ' + (self.pickerFace + self.pickerInset + y - Math.floor(colorDropper.images.arrow[1] / 2)) + 'px';
  7137. }
  7138. function isPickerOwner() {
  7139. return colorDropper.picker && colorDropper.picker.owner === self;
  7140. }
  7141. function blurTarget() {
  7142. if (valueElement === target) {
  7143. self.importColor();
  7144. }
  7145. }
  7146. function blurValue() {
  7147. if (valueElement !== target) {
  7148. self.importColor();
  7149. }
  7150. }
  7151. function setPad(e) {
  7152. var mpos = colorDropper.getRelMousePos(e),
  7153. x = mpos.x - self.pickerFace - self.pickerInset,
  7154. y = mpos.y - self.pickerFace - self.pickerInset;
  7155. switch (modeID) {
  7156. case 0:
  7157. self.fromHSV(x * (6 / (colorDropper.images.pad[0] - 1)), 1 - y / (colorDropper.images.pad[1] - 1), null, leaveSld);
  7158. break;
  7159. case 1:
  7160. self.fromHSV(x * (6 / (colorDropper.images.pad[0] - 1)), null, 1 - y / (colorDropper.images.pad[1] - 1), leaveSld);
  7161. break;
  7162. }
  7163. }
  7164. function setSld(e) {
  7165. var mpos = colorDropper.getRelMousePos(e),
  7166. y = mpos.y - self.pickerFace - self.pickerInset;
  7167. switch (modeID) {
  7168. case 0:
  7169. self.fromHSV(null, null, 1 - y / (colorDropper.images.sld[1] - 1), leavePad);
  7170. break;
  7171. case 1:
  7172. self.fromHSV(null, 1 - y / (colorDropper.images.sld[1] - 1), null, leavePad);
  7173. break;
  7174. }
  7175. }
  7176. function dispatchImmediateChange() {
  7177. if (self.onImmediateChange) {
  7178. var callback;
  7179. if (typeof self.onImmediateChange === 'string') {
  7180. callback = new Function(self.onImmediateChange);
  7181. } else {
  7182. callback = self.onImmediateChange;
  7183. }
  7184. callback.call(self);
  7185. }
  7186. }
  7187. if (valueElement) {
  7188. colorDropper.addEvent(valueElement, 'keyup', updateFieldEventHandler);
  7189. colorDropper.addEvent(valueElement, 'input', updateFieldEventHandler);
  7190. colorDropper.addEvent(valueElement, 'blur', blurValue);
  7191. valueElement.setAttribute('autocomplete', 'off');
  7192. }
  7193. this.importColor();
  7194. }
  7195. };
  7196. GB.colorDropper = colorDropper.color;
  7197. })();