123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065 |
- (function(){UEDITOR_CONFIG = window.UEDITOR_CONFIG || {};
- var baidu = window.baidu || {};
- window.baidu = baidu;
- window.UE = baidu.editor = {};
- UE.plugins = {};
- UE.commands = {};
- UE.instants = {};
- UE.I18N = {};
- UE.version = "1.2.5.0";
- var dom = UE.dom = {};
- /**
- * @file
- * @name UE.browser
- * @short Browser
- * @desc UEditor中采用的浏览器判断模块
- */
- var browser = UE.browser = function(){
- var agent = navigator.userAgent.toLowerCase(),
- opera = window.opera,
- browser = {
- /**
- * 检测浏览器是否为IE
- * @name ie
- * @grammar UE.browser.ie => true|false
- */
- ie : !!window.ActiveXObject,
- /**
- * 检测浏览器是否为Opera
- * @name opera
- * @grammar UE.browser.opera => true|false
- */
- opera : ( !!opera && opera.version ),
- /**
- * 检测浏览器是否为webkit内核
- * @name webkit
- * @grammar UE.browser.webkit => true|false
- */
- webkit : ( agent.indexOf( ' applewebkit/' ) > -1 ),
- /**
- * 检测浏览器是否为mac系统下的浏览器
- * @name mac
- * @grammar UE.browser.mac => true|false
- */
- mac : ( agent.indexOf( 'macintosh' ) > -1 ),
- /**
- * 检测浏览器是否处于怪异模式
- * @name quirks
- * @grammar UE.browser.quirks => true|false
- */
- quirks : ( document.compatMode == 'BackCompat' )
- };
- /**
- * 检测浏览器是否处为gecko内核
- * @name gecko
- * @grammar UE.browser.gecko => true|false
- */
- browser.gecko =( navigator.product == 'Gecko' && !browser.webkit && !browser.opera );
- var version = 0;
- // Internet Explorer 6.0+
- if ( browser.ie ){
- version = parseFloat( agent.match( /msie (\d+)/ )[1] );
- /**
- * 检测浏览器是否为 IE9 模式
- * @name ie9Compat
- * @grammar UE.browser.ie9Compat => true|false
- */
- browser.ie9Compat = document.documentMode == 9;
- /**
- * 检测浏览器是否为 IE8 浏览器
- * @name ie8
- * @grammar UE.browser.ie8 => true|false
- */
- browser.ie8 = !!document.documentMode;
- /**
- * 检测浏览器是否为 IE8 模式
- * @name ie8Compat
- * @grammar UE.browser.ie8Compat => true|false
- */
- browser.ie8Compat = document.documentMode == 8;
- /**
- * 检测浏览器是否运行在 兼容IE7模式
- * @name ie7Compat
- * @grammar UE.browser.ie7Compat => true|false
- */
- browser.ie7Compat = ( ( version == 7 && !document.documentMode )
- || document.documentMode == 7 );
- /**
- * 检测浏览器是否IE6模式或怪异模式
- * @name ie6Compat
- * @grammar UE.browser.ie6Compat => true|false
- */
- browser.ie6Compat = ( version < 7 || browser.quirks );
- }
- // Gecko.
- if ( browser.gecko ){
- var geckoRelease = agent.match( /rv:([\d\.]+)/ );
- if ( geckoRelease )
- {
- geckoRelease = geckoRelease[1].split( '.' );
- version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1;
- }
- }
- /**
- * 检测浏览器是否为chrome
- * @name chrome
- * @grammar UE.browser.chrome => true|false
- */
- if (/chrome\/(\d+\.\d)/i.test(agent)) {
- browser.chrome = + RegExp['\x241'];
- }
- /**
- * 检测浏览器是否为safari
- * @name safari
- * @grammar UE.browser.safari => true|false
- */
- if(/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)){
- browser.safari = + (RegExp['\x241'] || RegExp['\x242']);
- }
- // Opera 9.50+
- if ( browser.opera )
- version = parseFloat( opera.version() );
- // WebKit 522+ (Safari 3+)
- if ( browser.webkit )
- version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[1] );
- /**
- * 浏览器版本判断
- * IE系列返回值为5,6,7,8,9,10等
- * gecko系列会返回10900,158900等.
- * webkit系列会返回其build号 (如 522等).
- * @name version
- * @grammar UE.browser.version => number
- * @example
- * if ( UE.browser.ie && UE.browser.version == 6 ){
- * alert( "Ouch!居然是万恶的IE6!" );
- * }
- */
- browser.version = version;
- /**
- * 是否是兼容模式的浏览器
- * @name isCompatible
- * @grammar UE.browser.isCompatible => true|false
- * @example
- * if ( UE.browser.isCompatible ){
- * alert( "你的浏览器相当不错哦!" );
- * }
- */
- browser.isCompatible =
- !browser.mobile && (
- ( browser.ie && version >= 6 ) ||
- ( browser.gecko && version >= 10801 ) ||
- ( browser.opera && version >= 9.5 ) ||
- ( browser.air && version >= 1 ) ||
- ( browser.webkit && version >= 522 ) ||
- false );
- return browser;
- }();
- //快捷方式
- var ie = browser.ie,
- webkit = browser.webkit,
- gecko = browser.gecko,
- opera = browser.opera;
- /**
- * @file
- * @name UE.Utils
- * @short Utils
- * @desc UEditor封装使用的静态工具函数
- * @import editor.js
- */
- var utils = UE.utils = {
- /**
- * 遍历数组,对象,nodeList
- * @name each
- * @grammar UE.utils.each(obj,iterator,[context])
- * @since 1.2.4+
- * @desc
- * * obj 要遍历的对象
- * * iterator 遍历的方法,方法的第一个是遍历的值,第二个是索引,第三个是obj
- * * context iterator的上下文
- * @example
- * UE.utils.each([1,2],function(v,i){
- * console.log(v)//值
- * console.log(i)//索引
- * })
- * UE.utils.each(document.getElementsByTagName('*'),function(n){
- * console.log(n.tagName)
- * })
- */
- each : function(obj, iterator, context) {
- if (obj == null) return;
- if (obj.length === +obj.length) {
- for (var i = 0, l = obj.length; i < l; i++) {
- if(iterator.call(context, obj[i], i, obj) === false)
- return false;
- }
- } else {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- if(iterator.call(context, obj[key], key, obj) === false)
- return false;
- }
- }
- }
- },
- makeInstance:function (obj) {
- var noop = new Function();
- noop.prototype = obj;
- obj = new noop;
- noop.prototype = null;
- return obj;
- },
- /**
- * 将source对象中的属性扩展到target对象上
- * @name extend
- * @grammar UE.utils.extend(target,source) => Object //覆盖扩展
- * @grammar UE.utils.extend(target,source,true) ==> Object //保留扩展
- */
- extend:function (t, s, b) {
- if (s) {
- for (var k in s) {
- if (!b || !t.hasOwnProperty(k)) {
- t[k] = s[k];
- }
- }
- }
- return t;
- },
- /**
- * 模拟继承机制,subClass继承superClass
- * @name inherits
- * @grammar UE.utils.inherits(subClass,superClass) => subClass
- * @example
- * function SuperClass(){
- * this.name = "小李";
- * }
- * SuperClass.prototype = {
- * hello:function(str){
- * console.log(this.name + str);
- * }
- * }
- * function SubClass(){
- * this.name = "小张";
- * }
- * UE.utils.inherits(SubClass,SuperClass);
- * var sub = new SubClass();
- * sub.hello("早上好!"); ==> "小张早上好!"
- */
- inherits:function (subClass, superClass) {
- var oldP = subClass.prototype,
- newP = utils.makeInstance(superClass.prototype);
- utils.extend(newP, oldP, true);
- subClass.prototype = newP;
- return (newP.constructor = subClass);
- },
- /**
- * 用指定的context作为fn上下文,也就是this
- * @name bind
- * @grammar UE.utils.bind(fn,context) => fn
- */
- bind:function (fn, context) {
- return function () {
- return fn.apply(context, arguments);
- };
- },
- /**
- * 创建延迟delay执行的函数fn
- * @name defer
- * @grammar UE.utils.defer(fn,delay) =>fn //延迟delay毫秒执行fn,返回fn
- * @grammar UE.utils.defer(fn,delay,exclusion) =>fn //延迟delay毫秒执行fn,若exclusion为真,则互斥执行fn
- * @example
- * function test(){
- * console.log("延迟输出!");
- * }
- * //非互斥延迟执行
- * var testDefer = UE.utils.defer(test,1000);
- * testDefer(); => "延迟输出!";
- * testDefer(); => "延迟输出!";
- * //互斥延迟执行
- * var testDefer1 = UE.utils.defer(test,1000,true);
- * testDefer1(); => //本次不执行
- * testDefer1(); => "延迟输出!";
- */
- defer:function (fn, delay, exclusion) {
- var timerID;
- return function () {
- if (exclusion) {
- clearTimeout(timerID);
- }
- timerID = setTimeout(fn, delay);
- };
- },
- /**
- * 查找元素item在数组array中的索引, 若找不到返回-1
- * @name indexOf
- * @grammar UE.utils.indexOf(array,item) => index|-1 //默认从数组开头部开始搜索
- * @grammar UE.utils.indexOf(array,item,start) => index|-1 //start指定开始查找的位置
- */
- indexOf:function (array, item, start) {
- var index = -1;
- start = this.isNumber(start) ? start : 0;
- this.each(array,function(v,i){
- if(i >= start && v === item){
- index = i;
- return false;
- }
- });
- return index;
- },
- /**
- * 移除数组array中的元素item
- * @name removeItem
- * @grammar UE.utils.removeItem(array,item)
- */
- removeItem:function (array, item) {
- for (var i = 0, l = array.length; i < l; i++) {
- if (array[i] === item) {
- array.splice(i, 1);
- i--;
- }
- }
- },
- /**
- * 删除字符串str的首尾空格
- * @name trim
- * @grammar UE.utils.trim(str) => String
- */
- trim:function (str) {
- return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, '');
- },
- /**
- * 将字符串list(以','分隔)或者数组list转成哈希对象
- * @name listToMap
- * @grammar UE.utils.listToMap(list) => Object //Object形如{test:1,br:1,textarea:1}
- */
- listToMap:function (list) {
- if (!list)return {};
- list = utils.isArray(list) ? list : list.split(',');
- for (var i = 0, ci, obj = {}; ci = list[i++];) {
- obj[ci.toUpperCase()] = obj[ci] = 1;
- }
- return obj;
- },
- /**
- * 将str中的html符号转义,默认将转义''&<">''四个字符,可自定义reg来确定需要转义的字符
- * @name unhtml
- * @grammar UE.utils.unhtml(str); => String
- * @grammar UE.utils.unhtml(str,reg) => String
- * @example
- * var html = '<body>You say:"你好!Baidu & UEditor!"</body>';
- * UE.utils.unhtml(html); ==> <body>You say:"你好!Baidu & UEditor!"</body>
- * UE.utils.unhtml(html,/[<>]/g) ==> <body>You say:"你好!Baidu & UEditor!"</body>
- */
- unhtml:function (str, reg) {
- return str ? str.replace(reg || /[&<">]/g, function (m) {
- return {
- '<':'<',
- '&':'&',
- '"':'"',
- '>':'>'
- }[m]
- }) : '';
- },
- /**
- * 将str中的转义字符还原成html字符
- * @name html
- * @grammar UE.utils.html(str) => String //详细参见<code><a href = '#unhtml'>unhtml</a></code>
- */
- html:function (str) {
- return str ? str.replace(/&((g|l|quo)t|amp);/g, function (m) {
- return {
- '<':'<',
- '&':'&',
- '"':'"',
- '>':'>'
- }[m]
- }) : '';
- },
- /**
- * 将css样式转换为驼峰的形式。如font-size => fontSize
- * @name cssStyleToDomStyle
- * @grammar UE.utils.cssStyleToDomStyle(cssName) => String
- */
- cssStyleToDomStyle:function () {
- var test = document.createElement('div').style,
- cache = {
- 'float':test.cssFloat != undefined ? 'cssFloat' : test.styleFloat != undefined ? 'styleFloat' : 'float'
- };
- return function (cssName) {
- return cache[cssName] || (cache[cssName] = cssName.toLowerCase().replace(/-./g, function (match) {
- return match.charAt(1).toUpperCase();
- }));
- };
- }(),
- /**
- * 动态加载文件到doc中,并依据obj来设置属性,加载成功后执行回调函数fn
- * @name loadFile
- * @grammar UE.utils.loadFile(doc,obj)
- * @grammar UE.utils.loadFile(doc,obj,fn)
- * @example
- * //指定加载到当前document中一个script文件,加载成功后执行function
- * utils.loadFile( document, {
- * src:"test.js",
- * tag:"script",
- * type:"text/javascript",
- * defer:"defer"
- * }, function () {
- * console.log('加载成功!')
- * });
- */
- loadFile:function () {
- var tmpList = [];
- function getItem(doc,obj){
- try{
- for(var i= 0,ci;ci=tmpList[i++];){
- if(ci.doc === doc && ci.url == (obj.src || obj.href)){
- return ci;
- }
- }
- }catch(e){
- return null;
- }
- }
- return function (doc, obj, fn) {
- var item = getItem(doc,obj);
- if (item) {
- if(item.ready){
- fn && fn();
- }else{
- item.funs.push(fn)
- }
- return;
- }
- tmpList.push({
- doc:doc,
- url:obj.src||obj.href,
- funs:[fn]
- });
- if (!doc.body) {
- var html = [];
- for(var p in obj){
- if(p == 'tag')continue;
- html.push(p + '="' + obj[p] + '"')
- }
- doc.write('<' + obj.tag + ' ' + html.join(' ') + ' ></'+obj.tag+'>');
- return;
- }
- if (obj.id && doc.getElementById(obj.id)) {
- return;
- }
- var element = doc.createElement(obj.tag);
- delete obj.tag;
- for (var p in obj) {
- element.setAttribute(p, obj[p]);
- }
- element.onload = element.onreadystatechange = function () {
- if (!this.readyState || /loaded|complete/.test(this.readyState)) {
- item = getItem(doc,obj);
- if (item.funs.length > 0) {
- item.ready = 1;
- for (var fi; fi = item.funs.pop();) {
- fi();
- }
- }
- element.onload = element.onreadystatechange = null;
- }
- };
- element.onerror = function(){
- throw Error('The load '+(obj.href||obj.src)+' fails,check the url settings of file editor_config.js ')
- };
- doc.getElementsByTagName("head")[0].appendChild(element);
- }
- }(),
- /**
- * 判断obj对象是否为空
- * @name isEmptyObject
- * @grammar UE.utils.isEmptyObject(obj) => true|false
- * @example
- * UE.utils.isEmptyObject({}) ==>true
- * UE.utils.isEmptyObject([]) ==>true
- * UE.utils.isEmptyObject("") ==>true
- */
- isEmptyObject:function (obj) {
- if (obj == null) return true;
- if (this.isArray(obj) || this.isString(obj)) return obj.length === 0;
- for (var key in obj) if (obj.hasOwnProperty(key)) return false;
- return true;
- },
- /**
- * 统一将颜色值使用16进制形式表示
- * @name fixColor
- * @grammar UE.utils.fixColor(name,value) => value
- * @example
- * rgb(255,255,255) => "#ffffff"
- */
- fixColor:function (name, value) {
- if (/color/i.test(name) && /rgba?/.test(value)) {
- var array = value.split(",");
- if (array.length > 3)
- return "";
- value = "#";
- for (var i = 0, color; color = array[i++];) {
- color = parseInt(color.replace(/[^\d]/gi, ''), 10).toString(16);
- value += color.length == 1 ? "0" + color : color;
- }
- value = value.toUpperCase();
- }
- return value;
- },
- /**
- * 只针对border,padding,margin做了处理,因为性能问题
- * @public
- * @function
- * @param {String} val style字符串
- */
- optCss:function (val) {
- var padding, margin, border;
- val = val.replace(/(padding|margin|border)\-([^:]+):([^;]+);?/gi, function (str, key, name, val) {
- if (val.split(' ').length == 1) {
- switch (key) {
- case 'padding':
- !padding && (padding = {});
- padding[name] = val;
- return '';
- case 'margin':
- !margin && (margin = {});
- margin[name] = val;
- return '';
- case 'border':
- return val == 'initial' ? '' : str;
- }
- }
- return str;
- });
- function opt(obj, name) {
- if (!obj) {
- return '';
- }
- var t = obj.top , b = obj.bottom, l = obj.left, r = obj.right, val = '';
- if (!t || !l || !b || !r) {
- for (var p in obj) {
- val += ';' + name + '-' + p + ':' + obj[p] + ';';
- }
- } else {
- val += ';' + name + ':' +
- (t == b && b == l && l == r ? t :
- t == b && l == r ? (t + ' ' + l) :
- l == r ? (t + ' ' + l + ' ' + b) : (t + ' ' + r + ' ' + b + ' ' + l)) + ';'
- }
- return val;
- }
- val += opt(padding, 'padding') + opt(margin, 'margin');
- return val.replace(/^[ \n\r\t;]*|[ \n\r\t]*$/, '').replace(/;([ \n\r\t]+)|\1;/g, ';')
- .replace(/(&((l|g)t|quot|#39))?;{2,}/g, function (a, b) {
- return b ? b + ";;" : ';'
- });
- },
- /**
- * 深度克隆对象,从source到target
- * @name clone
- * @grammar UE.utils.clone(source) => anthorObj 新的对象是完整的source的副本
- * @grammar UE.utils.clone(source,target) => target包含了source的所有内容,重名会覆盖
- */
- clone:function (source, target) {
- var tmp;
- target = target || {};
- for (var i in source) {
- if (source.hasOwnProperty(i)) {
- tmp = source[i];
- if (typeof tmp == 'object') {
- target[i] = utils.isArray(tmp) ? [] : {};
- utils.clone(source[i], target[i])
- } else {
- target[i] = tmp;
- }
- }
- }
- return target;
- },
- /**
- * 转换cm/pt到px
- * @name transUnitToPx
- * @grammar UE.utils.transUnitToPx('20pt') => '27px'
- * @grammar UE.utils.transUnitToPx('0pt') => '0'
- */
- transUnitToPx : function(val){
- if(!/(pt|cm)/.test(val)){
- return val
- }
- var unit;
- val.replace(/([\d.]+)(\w+)/,function(str,v,u){
- val = v;
- unit = u;
- });
- switch(unit){
- case 'cm':
- val = parseFloat(val) * 25;
- break;
- case 'pt':
- val = Math.round(parseFloat(val) * 96 / 72);
- }
- return val + (val?'px':'');
- },
- /**
- * DomReady方法,回调函数将在dom树ready完成后执行
- * @name domReady
- * @grammar UE.utils.domReady(fn) => fn //返回一个延迟执行的方法
- */
- domReady:function () {
- var fnArr = [];
- function doReady(doc) {
- //确保onready只执行一次
- doc.isReady = true;
- for (var ci; ci = fnArr.pop();ci()){}
- }
- return function (onready,win) {
- win = win || window;
- var doc = win.document;
- onready && fnArr.push(onready);
- if (doc.readyState === "complete") {
- doReady(doc);
- }else{
- doc.isReady && doReady(doc);
- if (browser.ie) {
- (function () {
- if (doc.isReady) return;
- try {
- doc.documentElement.doScroll("left");
- } catch (error) {
- setTimeout(arguments.callee, 0);
- return;
- }
- doReady(doc);
- })();
- win.attachEvent('onload', function(){
- doReady(doc)
- });
- } else {
- doc.addEventListener("DOMContentLoaded", function () {
- doc.removeEventListener("DOMContentLoaded", arguments.callee, false);
- doReady(doc);
- }, false);
- win.addEventListener('load', function(){doReady(doc)}, false);
- }
- }
- }
- }(),
- /**
- * 动态添加css样式
- * @name cssRule
- * @grammar UE.utils.cssRule('添加的样式的节点名称',['样式','放到哪个document上'])
- * @grammar UE.utils.cssRule('body','body{background:#ccc}') => null //给body添加背景颜色
- * @grammar UE.utils.cssRule('body') =>样式的字符串 //取得key值为body的样式的内容,如果没有找到key值先关的样式将返回空,例如刚才那个背景颜色,将返回 body{background:#ccc}
- * @grammar UE.utils.cssRule('body','') =>null //清空给定的key值的背景颜色
- */
- cssRule : browser.ie ? function(key,style,doc){
- var indexList,index;
- doc = doc || document;
- if(doc.indexList){
- indexList = doc.indexList;
- }else{
- indexList = doc.indexList = {};
- }
- var sheetStyle;
- if(!indexList[key]){
- if(style === undefined){
- return ''
- }
- sheetStyle = doc.createStyleSheet('',index = doc.styleSheets.length);
- indexList[key] = index;
- }else{
- sheetStyle = doc.styleSheets[indexList[key]];
- }
- if(style === undefined){
- return sheetStyle.cssText
- }
- sheetStyle.cssText = style || ''
- }:function(key,style,doc){
- doc = doc || document;
- var head = doc.getElementsByTagName('head')[0],node;
- if(!(node = doc.getElementById(key))){
- if(style === undefined){
- return ''
- }
- node = doc.createElement('style');
- node.id = key;
- head.appendChild(node)
- }
- if(style === undefined){
- return node.innerHTML
- }
- if(style !== ''){
- node.innerHTML = style;
- }else{
- head.removeChild(node)
- }
- }
- };
- /**
- * 判断str是否为字符串
- * @name isString
- * @grammar UE.utils.isString(str) => true|false
- */
- /**
- * 判断array是否为数组
- * @name isArray
- * @grammar UE.utils.isArray(obj) => true|false
- */
- /**
- * 判断obj对象是否为方法
- * @name isFunction
- * @grammar UE.utils.isFunction(obj) => true|false
- */
- /**
- * 判断obj对象是否为数字
- * @name isNumber
- * @grammar UE.utils.isNumber(obj) => true|false
- */
- utils.each(['String','Function','Array','Number','RegExp'],function(v){
- UE.utils['is' + v] = function(obj){
- return Object.prototype.toString.apply(obj) == '[object ' + v + ']';
- }
- });
- /**
- * @file
- * @name UE.EventBase
- * @short EventBase
- * @import editor.js,core/utils.js
- * @desc UE采用的事件基类,继承此类的对应类将获取addListener,removeListener,fireEvent方法。
- * 在UE中,Editor以及所有ui实例都继承了该类,故可以在对应的ui对象以及editor对象上使用上述方法。
- */
- var EventBase = UE.EventBase = function () {};
- EventBase.prototype = {
- /**
- * 注册事件监听器
- * @name addListener
- * @grammar editor.addListener(types,fn) //types为事件名称,多个可用空格分隔
- * @example
- * editor.addListener('selectionchange',function(){
- * console.log("选区已经变化!");
- * })
- * editor.addListener('beforegetcontent aftergetcontent',function(type){
- * if(type == 'beforegetcontent'){
- * //do something
- * }else{
- * //do something
- * }
- * console.log(this.getContent) // this是注册的事件的编辑器实例
- * })
- */
- addListener:function (types, listener) {
- types = utils.trim(types).split(' ');
- for (var i = 0, ti; ti = types[i++];) {
- getListener(this, ti, true).push(listener);
- }
- },
- /**
- * 移除事件监听器
- * @name removeListener
- * @grammar editor.removeListener(types,fn) //types为事件名称,多个可用空格分隔
- * @example
- * //changeCallback为方法体
- * editor.removeListener("selectionchange",changeCallback);
- */
- removeListener:function (types, listener) {
- types = utils.trim(types).split(' ');
- for (var i = 0, ti; ti = types[i++];) {
- utils.removeItem(getListener(this, ti) || [], listener);
- }
- },
- /**
- * 触发事件
- * @name fireEvent
- * @grammar editor.fireEvent(types) //types为事件名称,多个可用空格分隔
- * @example
- * editor.fireEvent("selectionchange");
- */
- fireEvent:function (types) {
- types = utils.trim(types).split(' ');
- for (var i = 0, ti; ti = types[i++];) {
- var listeners = getListener(this, ti),
- r, t, k;
- if (listeners) {
- k = listeners.length;
- while (k--) {
- if(!listeners[k])continue;
- t = listeners[k].apply(this, arguments);
- if(t === true){
- return t;
- }
- if (t !== undefined) {
- r = t;
- }
- }
- }
- if (t = this['on' + ti.toLowerCase()]) {
- r = t.apply(this, arguments);
- }
- }
- return r;
- }
- };
- /**
- * 获得对象所拥有监听类型的所有监听器
- * @public
- * @function
- * @param {Object} obj 查询监听器的对象
- * @param {String} type 事件类型
- * @param {Boolean} force 为true且当前所有type类型的侦听器不存在时,创建一个空监听器数组
- * @returns {Array} 监听器数组
- */
- function getListener(obj, type, force) {
- var allListeners;
- type = type.toLowerCase();
- return ( ( allListeners = ( obj.__allListeners || force && ( obj.__allListeners = {} ) ) )
- && ( allListeners[type] || force && ( allListeners[type] = [] ) ) );
- }
- ///import editor.js
- ///import core/dom/dom.js
- /**
- * dtd html语义化的体现类
- * @constructor
- * @namespace dtd
- */
- var dtd = dom.dtd = (function() {
- function _( s ) {
- for (var k in s) {
- s[k.toUpperCase()] = s[k];
- }
- return s;
- }
- function X( t ) {
- var a = arguments;
- for ( var i=1; i<a.length; i++ ) {
- var x = a[i];
- for ( var k in x ) {
- if (!t.hasOwnProperty(k)) {
- t[k] = x[k];
- }
- }
- }
- return t;
- }
- var A = _({isindex:1,fieldset:1}),
- B = _({input:1,button:1,select:1,textarea:1,label:1}),
- C = X( _({a:1}), B ),
- D = X( {iframe:1}, C ),
- E = _({hr:1,ul:1,menu:1,div:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1}),
- F = _({ins:1,del:1,script:1,style:1}),
- G = X( _({b:1,acronym:1,bdo:1,'var':1,'#':1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1}), F ),
- H = X( _({sub:1,img:1,embed:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1}), G ),
- I = X( _({p:1}), H ),
- J = X( _({iframe:1}), H, B ),
- K = _({img:1,embed:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,'#':1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,'var':1,div:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1}),
- L = X( _({a:0}), J ),//a不能被切开,所以把他
- M = _({tr:1}),
- N = _({'#':1}),
- O = X( _({param:1}), K ),
- P = X( _({form:1}), A, D, E, I ),
- Q = _({li:1}),
- R = _({style:1,script:1}),
- S = _({base:1,link:1,meta:1,title:1}),
- T = X( S, R ),
- U = _({head:1,body:1}),
- V = _({html:1});
- var block = _({address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}),
- //针对优酷的embed他添加了结束标识,导致粘贴进来会变成两个,暂时去掉 ,embed:1
- empty = _({area:1,base:1,br:1,col:1,hr:1,img:1,input:1,link:1,meta:1,param:1,embed:1});
- return _({
- // $ 表示自定的属性
- // body外的元素列表.
- $nonBodyContent: X( V, U, S ),
- //块结构元素列表
- $block : block,
- //内联元素列表
- $inline : L,
- $body : X( _({script:1,style:1}), block ),
- $cdata : _({script:1,style:1}),
- //自闭和元素
- $empty : empty,
- //不是自闭合,但不能让range选中里边
- $nonChild : _({iframe:1,textarea:1}),
- //列表元素列表
- $listItem : _({dd:1,dt:1,li:1}),
- //列表根元素列表
- $list: _({ul:1,ol:1,dl:1}),
- //不能认为是空的元素
- $isNotEmpty : _({table:1,ul:1,ol:1,dl:1,iframe:1,area:1,base:1,col:1,hr:1,img:1,embed:1,input:1,link:1,meta:1,param:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1}),
- //如果没有子节点就可以删除的元素列表,像span,a
- $removeEmpty : _({a:1,abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1}),
- $removeEmptyBlock : _({'p':1,'div':1}),
- //在table元素里的元素列表
- $tableContent : _({caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1,table:1}),
- //不转换的标签
- $notTransContent : _({pre:1,script:1,style:1,textarea:1}),
- html: U,
- head: T,
- style: N,
- script: N,
- body: P,
- base: {},
- link: {},
- meta: {},
- title: N,
- col : {},
- tr : _({td:1,th:1}),
- img : {},
- embed: {},
- colgroup : _({thead:1,col:1,tbody:1,tr:1,tfoot:1}),
- noscript : P,
- td : P,
- br : {},
- th : P,
- center : P,
- kbd : L,
- button : X( I, E ),
- basefont : {},
- h5 : L,
- h4 : L,
- samp : L,
- h6 : L,
- ol : Q,
- h1 : L,
- h3 : L,
- option : N,
- h2 : L,
- form : X( A, D, E, I ),
- select : _({optgroup:1,option:1}),
- font : L,
- ins : L,
- menu : Q,
- abbr : L,
- label : L,
- table : _({thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1}),
- code : L,
- tfoot : M,
- cite : L,
- li : P,
- input : {},
- iframe : P,
- strong : L,
- textarea : N,
- noframes : P,
- big : L,
- small : L,
- span :_({'#':1,br:1}),
- hr : L,
- dt : L,
- sub : L,
- optgroup : _({option:1}),
- param : {},
- bdo : L,
- 'var' : L,
- div : P,
- object : O,
- sup : L,
- dd : P,
- strike : L,
- area : {},
- dir : Q,
- map : X( _({area:1,form:1,p:1}), A, F, E ),
- applet : O,
- dl : _({dt:1,dd:1}),
- del : L,
- isindex : {},
- fieldset : X( _({legend:1}), K ),
- thead : M,
- ul : Q,
- acronym : L,
- b : L,
- a : X( _({a:1}), J ),
- blockquote :X(_({td:1,tr:1,tbody:1,li:1}),P),
- caption : L,
- i : L,
- u : L,
- tbody : M,
- s : L,
- address : X( D, I ),
- tt : L,
- legend : L,
- q : L,
- pre : X( G, C ),
- p : X(_({'a':1}),L),
- em :L,
- dfn : L
- });
- })();
- /**
- * @file
- * @name UE.dom.domUtils
- * @short DomUtils
- * @import editor.js, core/utils.js,core/browser.js,core/dom/dtd.js
- * @desc UEditor封装的底层dom操作库
- */
- function getDomNode(node, start, ltr, startFromChild, fn, guard) {
- var tmpNode = startFromChild && node[start],
- parent;
- !tmpNode && (tmpNode = node[ltr]);
- while (!tmpNode && (parent = (parent || node).parentNode)) {
- if (parent.tagName == 'BODY' || guard && !guard(parent)) {
- return null;
- }
- tmpNode = parent[ltr];
- }
- if (tmpNode && fn && !fn(tmpNode)) {
- return getDomNode(tmpNode, start, ltr, false, fn);
- }
- return tmpNode;
- }
- var attrFix = ie && browser.version < 9 ? {
- tabindex:"tabIndex",
- readonly:"readOnly",
- "for":"htmlFor",
- "class":"className",
- maxlength:"maxLength",
- cellspacing:"cellSpacing",
- cellpadding:"cellPadding",
- rowspan:"rowSpan",
- colspan:"colSpan",
- usemap:"useMap",
- frameborder:"frameBorder"
- } : {
- tabindex:"tabIndex",
- readonly:"readOnly"
- },
- styleBlock = utils.listToMap([
- '-webkit-box', '-moz-box', 'block' ,
- 'list-item' , 'table' , 'table-row-group' ,
- 'table-header-group', 'table-footer-group' ,
- 'table-row' , 'table-column-group' , 'table-column' ,
- 'table-cell' , 'table-caption'
- ]);
- var domUtils = dom.domUtils = {
- //节点常量
- NODE_ELEMENT:1,
- NODE_DOCUMENT:9,
- NODE_TEXT:3,
- NODE_COMMENT:8,
- NODE_DOCUMENT_FRAGMENT:11,
- //位置关系
- POSITION_IDENTICAL:0,
- POSITION_DISCONNECTED:1,
- POSITION_FOLLOWING:2,
- POSITION_PRECEDING:4,
- POSITION_IS_CONTAINED:8,
- POSITION_CONTAINS:16,
- //ie6使用其他的会有一段空白出现
- fillChar:ie && browser.version == '6' ? '\ufeff' : '\u200B',
- //-------------------------Node部分--------------------------------
- keys:{
- /*Backspace*/ 8:1, /*Delete*/ 46:1,
- /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1,
- 37:1, 38:1, 39:1, 40:1,
- 13:1 /*enter*/
- },
- /**
- * 获取节点A相对于节点B的位置关系
- * @name getPosition
- * @grammar UE.dom.domUtils.getPosition(nodeA,nodeB) => Number
- * @example
- * switch (returnValue) {
- * case 0: //相等,同一节点
- * case 1: //无关,节点不相连
- * case 2: //跟随,即节点A头部位于节点B头部的后面
- * case 4: //前置,即节点A头部位于节点B头部的前面
- * case 8: //被包含,即节点A被节点B包含
- * case 10://组合类型,即节点A满足跟随节点B且被节点B包含。实际上,如果被包含,必定跟随,所以returnValue事实上不会存在8的情况。
- * case 16://包含,即节点A包含节点B
- * case 20://组合类型,即节点A满足前置节点A且包含节点B。同样,如果包含,必定前置,所以returnValue事实上也不会存在16的情况
- * }
- */
- getPosition:function (nodeA, nodeB) {
- // 如果两个节点是同一个节点
- if (nodeA === nodeB) {
- // domUtils.POSITION_IDENTICAL
- return 0;
- }
- var node,
- parentsA = [nodeA],
- parentsB = [nodeB];
- node = nodeA;
- while (node = node.parentNode) {
- // 如果nodeB是nodeA的祖先节点
- if (node === nodeB) {
- // domUtils.POSITION_IS_CONTAINED + domUtils.POSITION_FOLLOWING
- return 10;
- }
- parentsA.push(node);
- }
- node = nodeB;
- while (node = node.parentNode) {
- // 如果nodeA是nodeB的祖先节点
- if (node === nodeA) {
- // domUtils.POSITION_CONTAINS + domUtils.POSITION_PRECEDING
- return 20;
- }
- parentsB.push(node);
- }
- parentsA.reverse();
- parentsB.reverse();
- if (parentsA[0] !== parentsB[0]) {
- // domUtils.POSITION_DISCONNECTED
- return 1;
- }
- var i = -1;
- while (i++, parentsA[i] === parentsB[i]) {
- }
- nodeA = parentsA[i];
- nodeB = parentsB[i];
- while (nodeA = nodeA.nextSibling) {
- if (nodeA === nodeB) {
- // domUtils.POSITION_PRECEDING
- return 4
- }
- }
- // domUtils.POSITION_FOLLOWING
- return 2;
- },
- /**
- * 返回节点node在父节点中的索引位置
- * @name getNodeIndex
- * @grammar UE.dom.domUtils.getNodeIndex(node) => Number //索引值从0开始
- */
- getNodeIndex:function (node, ignoreTextNode) {
- var preNode = node,
- i = 0;
- while (preNode = preNode.previousSibling) {
- if (ignoreTextNode && preNode.nodeType == 3) {
- if(preNode.nodeType != preNode.nextSibling.nodeType ){
- i++;
- }
- continue;
- }
- i++;
- }
- return i;
- },
- /**
- * 检测节点node是否在节点doc的树上,实质上是检测是否被doc包含
- * @name inDoc
- * @grammar UE.dom.domUtils.inDoc(node,doc) => true|false
- */
- inDoc:function (node, doc) {
- return domUtils.getPosition(node, doc) == 10;
- },
- /**
- * 查找node节点的祖先节点
- * @name findParent
- * @grammar UE.dom.domUtils.findParent(node) => Element // 直接返回node节点的父节点
- * @grammar UE.dom.domUtils.findParent(node,filterFn) => Element //filterFn为过滤函数,node作为参数,返回true时才会将node作为符合要求的节点返回
- * @grammar UE.dom.domUtils.findParent(node,filterFn,includeSelf) => Element //includeSelf指定是否包含自身
- */
- findParent:function (node, filterFn, includeSelf) {
- if (node && !domUtils.isBody(node)) {
- node = includeSelf ? node : node.parentNode;
- while (node) {
- if (!filterFn || filterFn(node) || domUtils.isBody(node)) {
- return filterFn && !filterFn(node) && domUtils.isBody(node) ? null : node;
- }
- node = node.parentNode;
- }
- }
- return null;
- },
- /**
- * 通过tagName查找node节点的祖先节点
- * @name findParentByTagName
- * @grammar UE.dom.domUtils.findParentByTagName(node,tagNames) => Element //tagNames支持数组,区分大小写
- * @grammar UE.dom.domUtils.findParentByTagName(node,tagNames,includeSelf) => Element //includeSelf指定是否包含自身
- * @grammar UE.dom.domUtils.findParentByTagName(node,tagNames,includeSelf,excludeFn) => Element //excludeFn指定例外过滤条件,返回true时忽略该节点
- */
- findParentByTagName:function (node, tagNames, includeSelf, excludeFn) {
- tagNames = utils.listToMap(utils.isArray(tagNames) ? tagNames : [tagNames]);
- return domUtils.findParent(node, function (node) {
- return tagNames[node.tagName] && !(excludeFn && excludeFn(node));
- }, includeSelf);
- },
- /**
- * 查找节点node的祖先节点集合
- * @name findParents
- * @grammar UE.dom.domUtils.findParents(node) => Array //返回一个祖先节点数组集合,不包含自身
- * @grammar UE.dom.domUtils.findParents(node,includeSelf) => Array //返回一个祖先节点数组集合,includeSelf指定是否包含自身
- * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn) => Array //返回一个祖先节点数组集合,filterFn指定过滤条件,返回true的node将被选取
- * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn,closerFirst) => Array //返回一个祖先节点数组集合,closerFirst为true的话,node的直接父亲节点是数组的第0个
- */
- findParents:function (node, includeSelf, filterFn, closerFirst) {
- var parents = includeSelf && ( filterFn && filterFn(node) || !filterFn ) ? [node] : [];
- while (node = domUtils.findParent(node, filterFn)) {
- parents.push(node);
- }
- return closerFirst ? parents : parents.reverse();
- },
- /**
- * 在节点node后面插入新节点newNode
- * @name insertAfter
- * @grammar UE.dom.domUtils.insertAfter(node,newNode) => newNode
- */
- insertAfter:function (node, newNode) {
- return node.parentNode.insertBefore(newNode, node.nextSibling);
- },
- /**
- * 删除节点node,并根据keepChildren指定是否保留子节点
- * @name remove
- * @grammar UE.dom.domUtils.remove(node) => node
- * @grammar UE.dom.domUtils.remove(node,keepChildren) => node
- */
- remove:function (node, keepChildren) {
- var parent = node.parentNode,
- child;
- if (parent) {
- if (keepChildren && node.hasChildNodes()) {
- while (child = node.firstChild) {
- parent.insertBefore(child, node);
- }
- }
- parent.removeChild(node);
- }
- return node;
- },
- /**
- * 取得node节点在dom树上的下一个节点,即多叉树遍历
- * @name getNextDomNode
- * @grammar UE.dom.domUtils.getNextDomNode(node) => Element
- * @example
- */
- getNextDomNode:function (node, startFromChild, filterFn, guard) {
- return getDomNode(node, 'firstChild', 'nextSibling', startFromChild, filterFn, guard);
- },
- /**
- * 检测节点node是否属于bookmark节点
- * @name isBookmarkNode
- * @grammar UE.dom.domUtils.isBookmarkNode(node) => true|false
- */
- isBookmarkNode:function (node) {
- return node.nodeType == 1 && node.id && /^_baidu_bookmark_/i.test(node.id);
- },
- /**
- * 获取节点node所在的window对象
- * @name getWindow
- * @grammar UE.dom.domUtils.getWindow(node) => window对象
- */
- getWindow:function (node) {
- var doc = node.ownerDocument || node;
- return doc.defaultView || doc.parentWindow;
- },
- /**
- * 得到nodeA与nodeB公共的祖先节点
- * @name getCommonAncestor
- * @grammar UE.dom.domUtils.getCommonAncestor(nodeA,nodeB) => Element
- */
- getCommonAncestor:function (nodeA, nodeB) {
- if (nodeA === nodeB)
- return nodeA;
- var parentsA = [nodeA] , parentsB = [nodeB], parent = nodeA, i = -1;
- while (parent = parent.parentNode) {
- if (parent === nodeB) {
- return parent;
- }
- parentsA.push(parent);
- }
- parent = nodeB;
- while (parent = parent.parentNode) {
- if (parent === nodeA)
- return parent;
- parentsB.push(parent);
- }
- parentsA.reverse();
- parentsB.reverse();
- while (i++, parentsA[i] === parentsB[i]) {
- }
- return i == 0 ? null : parentsA[i - 1];
- },
- /**
- * 清除node节点左右兄弟为空的inline节点
- * @name clearEmptySibling
- * @grammar UE.dom.domUtils.clearEmptySibling(node)
- * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext) //ignoreNext指定是否忽略右边空节点
- * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext,ignorePre) //ignorePre指定是否忽略左边空节点
- * @example
- * <b></b><i></i>xxxx<b>bb</b> --> xxxx<b>bb</b>
- */
- clearEmptySibling:function (node, ignoreNext, ignorePre) {
- function clear(next, dir) {
- var tmpNode;
- while (next && !domUtils.isBookmarkNode(next) && (domUtils.isEmptyInlineElement(next)
- //这里不能把空格算进来会吧空格干掉,出现文字间的空格丢掉了
- || !new RegExp('[^\t\n\r' + domUtils.fillChar + ']').test(next.nodeValue) )) {
- tmpNode = next[dir];
- domUtils.remove(next);
- next = tmpNode;
- }
- }
- !ignoreNext && clear(node.nextSibling, 'nextSibling');
- !ignorePre && clear(node.previousSibling, 'previousSibling');
- },
- /**
- * 将一个文本节点node拆分成两个文本节点,offset指定拆分位置
- * @name split
- * @grammar UE.dom.domUtils.split(node,offset) => TextNode //返回从切分位置开始的后一个文本节点
- */
- split:function (node, offset) {
- var doc = node.ownerDocument;
- if (browser.ie && offset == node.nodeValue.length) {
- var next = doc.createTextNode('');
- return domUtils.insertAfter(node, next);
- }
- var retval = node.splitText(offset);
- //ie8下splitText不会跟新childNodes,我们手动触发他的更新
- if (browser.ie8) {
- var tmpNode = doc.createTextNode('');
- domUtils.insertAfter(retval, tmpNode);
- domUtils.remove(tmpNode);
- }
- return retval;
- },
- /**
- * 检测节点node是否为空节点(包括空格、换行、占位符等字符)
- * @name isWhitespace
- * @grammar UE.dom.domUtils.isWhitespace(node) => true|false
- */
- isWhitespace:function (node) {
- return !new RegExp('[^ \t\n\r' + domUtils.fillChar + ']').test(node.nodeValue);
- },
- /**
- * 获取元素element相对于viewport的位置坐标
- * @name getXY
- * @grammar UE.dom.domUtils.getXY(element) => Object //返回坐标对象{x:left,y:top}
- */
- getXY:function (element) {
- var x = 0, y = 0;
- while (element.offsetParent) {
- y += element.offsetTop;
- x += element.offsetLeft;
- element = element.offsetParent;
- }
- return { 'x':x, 'y':y};
- },
- /**
- * 为元素element绑定原生DOM事件,type为事件类型,handler为处理函数
- * @name on
- * @grammar UE.dom.domUtils.on(element,type,handler) //type支持数组传入
- * @example
- * UE.dom.domUtils.on(document.body,"click",function(e){
- * //e为事件对象,this为被点击元素对戏那个
- * })
- * @example
- * UE.dom.domUtils.on(document.body,["click","mousedown"],function(evt){
- * //evt为事件对象,this为被点击元素对象
- * })
- */
- on:function (element, type, handler) {
- var types = utils.isArray(type) ? type : [type],
- k = types.length;
- if (k) while (k--) {
- type = types[k];
- if (element.addEventListener) {
- element.addEventListener(type, handler, false);
- } else {
- if (!handler._d) {
- handler._d = {
- els : []
- };
- }
- var key = type + handler.toString(),index = utils.indexOf(handler._d.els,element);
- if (!handler._d[key] || index == -1) {
- if(index == -1){
- handler._d.els.push(element);
- }
- if(!handler._d[key]){
- handler._d[key] = function (evt) {
- return handler.call(evt.srcElement, evt || window.event);
- };
- }
- element.attachEvent('on' + type, handler._d[key]);
- }
- }
- }
- element = null;
- },
- /**
- * 解除原生DOM事件绑定
- * @name un
- * @grammar UE.dom.donUtils.un(element,type,handler) //参见<code><a href="#on">on</a></code>
- */
- un:function (element, type, handler) {
- var types = utils.isArray(type) ? type : [type],
- k = types.length;
- if (k) while (k--) {
- type = types[k];
- if (element.removeEventListener) {
- element.removeEventListener(type, handler, false);
- } else {
- var key = type + handler.toString();
- try{
- element.detachEvent('on' + type, handler._d ? handler._d[key] : handler);
- }catch(e){}
- if (handler._d && handler._d[key]) {
- var index = utils.indexOf(handler._d.els,element);
- if(index!=-1){
- handler._d.els.splice(index,1);
- }
- handler._d.els.length == 0 && delete handler._d[key];
- }
- }
- }
- },
- /**
- * 比较节点nodeA与节点nodeB是否具有相同的标签名、属性名以及属性值
- * @name isSameElement
- * @grammar UE.dom.domUtils.isSameElement(nodeA,nodeB) => true|false
- * @example
- * <span style="font-size:12px">ssss</span> and <span style="font-size:12px">bbbbb</span> => true
- * <span style="font-size:13px">ssss</span> and <span style="font-size:12px">bbbbb</span> => false
- */
- isSameElement:function (nodeA, nodeB) {
- if (nodeA.tagName != nodeB.tagName) {
- return false;
- }
- var thisAttrs = nodeA.attributes,
- otherAttrs = nodeB.attributes;
- if (!ie && thisAttrs.length != otherAttrs.length) {
- return false;
- }
- var attrA, attrB, al = 0, bl = 0;
- for (var i = 0; attrA = thisAttrs[i++];) {
- if (attrA.nodeName == 'style') {
- if (attrA.specified) {
- al++;
- }
- if (domUtils.isSameStyle(nodeA, nodeB)) {
- continue;
- } else {
- return false;
- }
- }
- if (ie) {
- if (attrA.specified) {
- al++;
- attrB = otherAttrs.getNamedItem(attrA.nodeName);
- } else {
- continue;
- }
- } else {
- attrB = nodeB.attributes[attrA.nodeName];
- }
- if (!attrB.specified || attrA.nodeValue != attrB.nodeValue) {
- return false;
- }
- }
- // 有可能attrB的属性包含了attrA的属性之外还有自己的属性
- if (ie) {
- for (i = 0; attrB = otherAttrs[i++];) {
- if (attrB.specified) {
- bl++;
- }
- }
- if (al != bl) {
- return false;
- }
- }
- return true;
- },
- /**
- * 判断节点nodeA与节点nodeB的元素属性是否一致
- * @name isSameStyle
- * @grammar UE.dom.domUtils.isSameStyle(nodeA,nodeB) => true|false
- */
- isSameStyle:function (nodeA, nodeB) {
- var styleA = nodeA.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':'),
- styleB = nodeB.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':');
- if (browser.opera) {
- styleA = nodeA.style;
- styleB = nodeB.style;
- if (styleA.length != styleB.length)
- return false;
- for (var p in styleA) {
- if (/^(\d+|csstext)$/i.test(p)) {
- continue;
- }
- if (styleA[p] != styleB[p]) {
- return false;
- }
- }
- return true;
- }
- if (!styleA || !styleB) {
- return styleA == styleB;
- }
- styleA = styleA.split(';');
- styleB = styleB.split(';');
- if (styleA.length != styleB.length) {
- return false;
- }
- for (var i = 0, ci; ci = styleA[i++];) {
- if (utils.indexOf(styleB, ci) == -1) {
- return false;
- }
- }
- return true;
- },
- /**
- * 检查节点node是否为块元素
- * @name isBlockElm
- * @grammar UE.dom.domUtils.isBlockElm(node) => true|false
- */
- isBlockElm:function (node) {
- return node.nodeType == 1 && (dtd.$block[node.tagName] || styleBlock[domUtils.getComputedStyle(node, 'display')]) && !dtd.$nonChild[node.tagName];
- },
- /**
- * 检测node节点是否为body节点
- * @name isBody
- * @grammar UE.dom.domUtils.isBody(node) => true|false
- */
- isBody:function (node) {
- return node && node.nodeType == 1 && node.tagName.toLowerCase() == 'body';
- },
- /**
- * 以node节点为中心,将该节点的指定祖先节点parent拆分成2块
- * @name breakParent
- * @grammar UE.dom.domUtils.breakParent(node,parent) => node
- * @desc
- * <code type="html"><b>ooo</b>是node节点
- * <p>xxxx<b>ooo</b>xxx</p> ==> <p>xxx</p><b>ooo</b><p>xxx</p>
- * <p>xxxxx<span>xxxx<b>ooo</b>xxxxxx</span></p> => <p>xxxxx<span>xxxx</span></p><b>ooo</b><p><span>xxxxxx</span></p></code>
- */
- breakParent:function (node, parent) {
- var tmpNode,
- parentClone = node,
- clone = node,
- leftNodes,
- rightNodes;
- do {
- parentClone = parentClone.parentNode;
- if (leftNodes) {
- tmpNode = parentClone.cloneNode(false);
- tmpNode.appendChild(leftNodes);
- leftNodes = tmpNode;
- tmpNode = parentClone.cloneNode(false);
- tmpNode.appendChild(rightNodes);
- rightNodes = tmpNode;
- } else {
- leftNodes = parentClone.cloneNode(false);
- rightNodes = leftNodes.cloneNode(false);
- }
- while (tmpNode = clone.previousSibling) {
- leftNodes.insertBefore(tmpNode, leftNodes.firstChild);
- }
- while (tmpNode = clone.nextSibling) {
- rightNodes.appendChild(tmpNode);
- }
- clone = parentClone;
- } while (parent !== parentClone);
- tmpNode = parent.parentNode;
- tmpNode.insertBefore(leftNodes, parent);
- tmpNode.insertBefore(rightNodes, parent);
- tmpNode.insertBefore(node, rightNodes);
- domUtils.remove(parent);
- return node;
- },
- /**
- * 检查节点node是否是空inline节点
- * @name isEmptyInlineElement
- * @grammar UE.dom.domUtils.isEmptyInlineElement(node) => 1|0
- * @example
- * <b><i></i></b> => 1
- * <b><i></i><u></u></b> => 1
- * <b></b> => 1
- * <b>xx<i></i></b> => 0
- */
- isEmptyInlineElement:function (node) {
- if (node.nodeType != 1 || !dtd.$removeEmpty[ node.tagName ]) {
- return 0;
- }
- node = node.firstChild;
- while (node) {
- //如果是创建的bookmark就跳过
- if (domUtils.isBookmarkNode(node)) {
- return 0;
- }
- if (node.nodeType == 1 && !domUtils.isEmptyInlineElement(node) ||
- node.nodeType == 3 && !domUtils.isWhitespace(node)
- ) {
- return 0;
- }
- node = node.nextSibling;
- }
- return 1;
- },
- /**
- * 删除node节点下的左右空白文本子节点
- * @name trimWhiteTextNode
- * @grammar UE.dom.domUtils.trimWhiteTextNode(node)
- */
- trimWhiteTextNode:function (node) {
- function remove(dir) {
- var child;
- while ((child = node[dir]) && child.nodeType == 3 && domUtils.isWhitespace(child)) {
- node.removeChild(child);
- }
- }
- remove('firstChild');
- remove('lastChild');
- },
- /**
- * 合并node节点下相同的子节点
- * @name mergeChild
- * @desc
- * UE.dom.domUtils.mergeChild(node,tagName) //tagName要合并的子节点的标签
- * @example
- * <p><span style="font-size:12px;">xx<span style="font-size:12px;">aa</span>xx</span></p>
- * ==> UE.dom.domUtils.mergeChild(node,'span')
- * <p><span style="font-size:12px;">xxaaxx</span></p>
- */
- mergeChild:function (node, tagName, attrs) {
- var list = domUtils.getElementsByTagName(node, node.tagName.toLowerCase());
- for (var i = 0, ci; ci = list[i++];) {
- if (!ci.parentNode || domUtils.isBookmarkNode(ci)) {
- continue;
- }
- //span单独处理
- if (ci.tagName.toLowerCase() == 'span') {
- if (node === ci.parentNode) {
- domUtils.trimWhiteTextNode(node);
- if (node.childNodes.length == 1) {
- node.style.cssText = ci.style.cssText + ";" + node.style.cssText;
- domUtils.remove(ci, true);
- continue;
- }
- }
- ci.style.cssText = node.style.cssText + ';' + ci.style.cssText;
- if (attrs) {
- var style = attrs.style;
- if (style) {
- style = style.split(';');
- for (var j = 0, s; s = style[j++];) {
- ci.style[utils.cssStyleToDomStyle(s.split(':')[0])] = s.split(':')[1];
- }
- }
- }
- if (domUtils.isSameStyle(ci, node)) {
- domUtils.remove(ci, true);
- }
- continue;
- }
- if (domUtils.isSameElement(node, ci)) {
- domUtils.remove(ci, true);
- }
- }
- },
- /**
- * 原生方法getElementsByTagName的封装
- * @name getElementsByTagName
- * @grammar UE.dom.domUtils.getElementsByTagName(node,tagName) => Array //节点集合数组
- */
- getElementsByTagName:function (node, name,filter) {
- if(filter && utils.isString(filter)){
- var className = filter;
- filter = function(node){return domUtils.hasClass(node,className)}
- }
- name = utils.trim(name).replace(/[ ]{2,}/g,' ').split(' ');
- var arr = [];
- for(var n = 0,ni;ni=name[n++];){
- var list = node.getElementsByTagName(ni);
- for (var i = 0, ci; ci = list[i++];) {
- if(!filter || filter(ci))
- arr.push(ci);
- }
- }
- return arr;
- },
- /**
- * 将节点node合并到父节点上
- * @name mergeToParent
- * @grammar UE.dom.domUtils.mergeToParent(node)
- * @example
- * <span style="color:#fff"><span style="font-size:12px">xxx</span></span> ==> <span style="color:#fff;font-size:12px">xxx</span>
- */
- mergeToParent:function (node) {
- var parent = node.parentNode;
- while (parent && dtd.$removeEmpty[parent.tagName]) {
- if (parent.tagName == node.tagName || parent.tagName == 'A') {//针对a标签单独处理
- domUtils.trimWhiteTextNode(parent);
- //span需要特殊处理 不处理这样的情况 <span stlye="color:#fff">xxx<span style="color:#ccc">xxx</span>xxx</span>
- if (parent.tagName == 'SPAN' && !domUtils.isSameStyle(parent, node)
- || (parent.tagName == 'A' && node.tagName == 'SPAN')) {
- if (parent.childNodes.length > 1 || parent !== node.parentNode) {
- node.style.cssText = parent.style.cssText + ";" + node.style.cssText;
- parent = parent.parentNode;
- continue;
- } else {
- parent.style.cssText += ";" + node.style.cssText;
- //trace:952 a标签要保持下划线
- if (parent.tagName == 'A') {
- parent.style.textDecoration = 'underline';
- }
- }
- }
- if (parent.tagName != 'A') {
- parent === node.parentNode && domUtils.remove(node, true);
- break;
- }
- }
- parent = parent.parentNode;
- }
- },
- /**
- * 合并节点node的左右兄弟节点
- * @name mergeSibling
- * @grammar UE.dom.domUtils.mergeSibling(node)
- * @grammar UE.dom.domUtils.mergeSibling(node,ignorePre) //ignorePre指定是否忽略左兄弟
- * @grammar UE.dom.domUtils.mergeSibling(node,ignorePre,ignoreNext) //ignoreNext指定是否忽略右兄弟
- * @example
- * <b>xxxx</b><b>ooo</b><b>xxxx</b> ==> <b>xxxxoooxxxx</b>
- */
- mergeSibling:function (node, ignorePre, ignoreNext) {
- function merge(rtl, start, node) {
- var next;
- if ((next = node[rtl]) && !domUtils.isBookmarkNode(next) && next.nodeType == 1 && domUtils.isSameElement(node, next)) {
- while (next.firstChild) {
- if (start == 'firstChild') {
- node.insertBefore(next.lastChild, node.firstChild);
- } else {
- node.appendChild(next.firstChild);
- }
- }
- domUtils.remove(next);
- }
- }
- !ignorePre && merge('previousSibling', 'firstChild', node);
- !ignoreNext && merge('nextSibling', 'lastChild', node);
- },
- /**
- * 设置节点node及其子节点不会被选中
- * @name unSelectable
- * @grammar UE.dom.domUtils.unSelectable(node)
- */
- unSelectable:ie || browser.opera ? function (node) {
- //for ie9
- node.onselectstart = function () {
- return false;
- };
- node.onclick = node.onkeyup = node.onkeydown = function () {
- return false;
- };
- node.unselectable = 'on';
- node.setAttribute("unselectable", "on");
- for (var i = 0, ci; ci = node.all[i++];) {
- switch (ci.tagName.toLowerCase()) {
- case 'iframe' :
- case 'textarea' :
- case 'input' :
- case 'select' :
- break;
- default :
- ci.unselectable = 'on';
- node.setAttribute("unselectable", "on");
- }
- }
- } : function (node) {
- node.style.MozUserSelect =
- node.style.webkitUserSelect =
- node.style.KhtmlUserSelect = 'none';
- },
- /**
- * 删除节点node上的属性attrNames,attrNames为属性名称数组
- * @name removeAttributes
- * @grammar UE.dom.domUtils.removeAttributes(node,attrNames)
- * @example
- * //Before remove
- * <span style="font-size:14px;" id="test" name="followMe">xxxxx</span>
- * //Remove
- * UE.dom.domUtils.removeAttributes(node,["id","name"]);
- * //After remove
- * <span style="font-size:14px;">xxxxx</span>
- */
- removeAttributes:function (node, attrNames) {
- attrNames = utils.isArray(attrNames) ? attrNames : utils.trim(attrNames).replace(/[ ]{2,}/g,' ').split(' ');
- for (var i = 0, ci; ci = attrNames[i++];) {
- ci = attrFix[ci] || ci;
- switch (ci) {
- case 'className':
- node[ci] = '';
- break;
- case 'style':
- node.style.cssText = '';
- !browser.ie && node.removeAttributeNode(node.getAttributeNode('style'))
- }
- node.removeAttribute(ci);
- }
- },
- /**
- * 在doc下创建一个标签名为tag,属性为attrs的元素
- * @name createElement
- * @grammar UE.dom.domUtils.createElement(doc,tag,attrs) => Node //返回创建的节点
- */
- createElement:function (doc, tag, attrs) {
- return domUtils.setAttributes(doc.createElement(tag), attrs)
- },
- /**
- * 为节点node添加属性attrs,attrs为属性键值对
- * @name setAttributes
- * @grammar UE.dom.domUtils.setAttributes(node,attrs) => node
- */
- setAttributes:function (node, attrs) {
- for (var attr in attrs) {
- if(attrs.hasOwnProperty(attr)){
- var value = attrs[attr];
- switch (attr) {
- case 'class':
- //ie下要这样赋值,setAttribute不起作用
- node.className = value;
- break;
- case 'style' :
- node.style.cssText = node.style.cssText + ";" + value;
- break;
- case 'innerHTML':
- node[attr] = value;
- break;
- case 'value':
- node.value = value;
- break;
- default:
- node.setAttribute(attrFix[attr] || attr, value);
- }
- }
- }
- return node;
- },
- /**
- * 获取元素element的计算样式
- * @name getComputedStyle
- * @grammar UE.dom.domUtils.getComputedStyle(element,styleName) => String //返回对应样式名称的样式值
- * @example
- * getComputedStyle(document.body,"font-size") => "15px"
- * getComputedStyle(form,"color") => "#ffccdd"
- */
- getComputedStyle:function (element, styleName) {
- //一下的属性单独处理
- var pros = 'width height top left';
- if(pros.indexOf(styleName) > -1){
- return element['offset' + styleName.replace(/^\w/,function(s){return s.toUpperCase()})] + 'px';
- }
- //忽略文本节点
- if (element.nodeType == 3) {
- element = element.parentNode;
- }
- //ie下font-size若body下定义了font-size,则从currentStyle里会取到这个font-size. 取不到实际值,故此修改.
- if (browser.ie && browser.version < 9 && styleName == 'font-size' && !element.style.fontSize &&
- !dtd.$empty[element.tagName] && !dtd.$nonChild[element.tagName]) {
- var span = element.ownerDocument.createElement('span');
- span.style.cssText = 'padding:0;border:0;font-family:simsun;';
- span.innerHTML = '.';
- element.appendChild(span);
- var result = span.offsetHeight;
- element.removeChild(span);
- span = null;
- return result + 'px';
- }
- try {
- var value = domUtils.getStyle(element, styleName) ||
- (window.getComputedStyle ? domUtils.getWindow(element).getComputedStyle(element, '').getPropertyValue(styleName) :
- ( element.currentStyle || element.style )[utils.cssStyleToDomStyle(styleName)]);
- } catch (e) {
- return "";
- }
- return utils.transUnitToPx(utils.fixColor(styleName, value));
- },
- /**
- * 在元素element上删除classNames,支持同时删除多个
- * @name removeClasses
- * @grammar UE.dom.domUtils.removeClasses(element,classNames)
- * @example
- * //执行方法前的dom结构
- * <span class="test1 test2 test3">xxx</span>
- * //执行方法
- * UE.dom.domUtils.removeClasses(element,["test1","test3"])
- * //执行方法后的dom结构
- * <span class="test2">xxx</span>
- */
- removeClasses:function (elm, classNames) {
- classNames = utils.isArray(classNames) ? classNames :
- utils.trim(classNames).replace(/[ ]{2,}/g,' ').split(' ');
- for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){
- cls = cls.replace(new RegExp('\\b' + ci + '\\b'),'')
- }
- cls = utils.trim(cls).replace(/[ ]{2,}/g,' ');
- if(cls){
- elm.className = cls;
- }else{
- domUtils.removeAttributes(elm,['class']);
- }
- },
- /**
- * 在元素element上增加一个样式类className,支持以空格分开的多个类名
- * 如果相同的类名将不会添加
- * @name addClass
- * @grammar UE.dom.domUtils.addClass(element,classNames)
- */
- addClass:function (elm, classNames) {
- if(!elm)return;
- classNames = utils.trim(classNames).replace(/[ ]{2,}/g,' ').split(' ');
- for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){
- if(!new RegExp('\\b' + ci + '\\b').test(cls)){
- elm.className += ' ' + ci;
- }
- }
- },
- /**
- * 判断元素element是否包含样式类名className,支持以空格分开的多个类名,多个类名顺序不同也可以比较
- * @name hasClass
- * @grammar UE.dom.domUtils.hasClass(element,className) =>true|false
- */
- hasClass:function (element, className) {
- if(utils.isRegExp(className)){
- return className.test(element.className)
- }
- className = utils.trim(className).replace(/[ ]{2,}/g,' ').split(' ');
- for(var i = 0,ci,cls = element.className;ci=className[i++];){
- if(!new RegExp('\\b' + ci + '\\b','i').test(cls)){
- return false;
- }
- }
- return i - 1 == className.length;
- },
- /**
- * 阻止事件默认行为
- * @param {Event} evt 需要组织的事件对象
- */
- preventDefault:function (evt) {
- evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);
- },
- /**
- * 删除元素element的样式
- * @grammar UE.dom.domUtils.removeStyle(element,name) 删除的样式名称
- */
- removeStyle:function (element, name) {
- if(browser.ie && browser.version > 8){
- element.style.cssText = element.style.cssText.replace(new RegExp(name + '\s*:\s*[^;]+;?'),'')
- }else{
- if (element.style.removeProperty) {
- element.style.removeProperty (name);
- }else {
- element.style.removeAttribute (utils.cssStyleToDomStyle(name));
- }
- }
- if (!element.style.cssText) {
- domUtils.removeAttributes(element, ['style']);
- }
- },
- /**
- * 获取元素element的某个样式值
- * @name getStyle
- * @grammar UE.dom.domUtils.getStyle(element,name) => String
- */
- getStyle:function (element, name) {
- var value = element.style[ utils.cssStyleToDomStyle(name) ];
- return utils.fixColor(name, value);
- },
- /**
- * 为元素element设置样式属性值
- * @name setStyle
- * @grammar UE.dom.domUtils.setStyle(element,name,value)
- */
- setStyle:function (element, name, value) {
- element.style[utils.cssStyleToDomStyle(name)] = value;
- },
- /**
- * 为元素element设置样式属性值
- * @name setStyles
- * @grammar UE.dom.domUtils.setStyle(element,styles) //styles为样式键值对
- */
- setStyles:function (element, styles) {
- for (var name in styles) {
- if (styles.hasOwnProperty(name)) {
- domUtils.setStyle(element, name, styles[name]);
- }
- }
- },
- /**
- * 删除_moz_dirty属性
- * @function
- */
- removeDirtyAttr:function (node) {
- for (var i = 0, ci, nodes = node.getElementsByTagName('*'); ci = nodes[i++];) {
- ci.removeAttribute('_moz_dirty');
- }
- node.removeAttribute('_moz_dirty');
- },
- /**
- * 返回子节点的数量
- * @function
- * @param {Node} node 父节点
- * @param {Function} fn 过滤子节点的规则,若为空,则得到所有子节点的数量
- * @return {Number} 符合条件子节点的数量
- */
- getChildCount:function (node, fn) {
- var count = 0, first = node.firstChild;
- fn = fn || function () {
- return 1;
- };
- while (first) {
- if (fn(first)) {
- count++;
- }
- first = first.nextSibling;
- }
- return count;
- },
- /**
- * 判断是否为空节点
- * @function
- * @param {Node} node 节点
- * @return {Boolean} 是否为空节点
- */
- isEmptyNode:function (node) {
- return !node.firstChild || domUtils.getChildCount(node, function (node) {
- return !domUtils.isBr(node) && !domUtils.isBookmarkNode(node) && !domUtils.isWhitespace(node)
- }) == 0
- },
- /**
- * 清空节点所有的className
- * @function
- * @param {Array} nodes 节点数组
- */
- clearSelectedArr:function (nodes) {
- var node;
- while (node = nodes.pop()) {
- domUtils.removeAttributes(node, ['class']);
- }
- },
- /**
- * 将显示区域滚动到显示节点的位置
- * @function
- * @param {Node} node 节点
- * @param {window} win window对象
- * @param {Number} offsetTop 距离上方的偏移量
- */
- scrollToView:function (node, win, offsetTop) {
- var getViewPaneSize = function () {
- var doc = win.document,
- mode = doc.compatMode == 'CSS1Compat';
- return {
- width:( mode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0,
- height:( mode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0
- };
- },
- getScrollPosition = function (win) {
- if ('pageXOffset' in win) {
- return {
- x:win.pageXOffset || 0,
- y:win.pageYOffset || 0
- };
- }
- else {
- var doc = win.document;
- return {
- x:doc.documentElement.scrollLeft || doc.body.scrollLeft || 0,
- y:doc.documentElement.scrollTop || doc.body.scrollTop || 0
- };
- }
- };
- var winHeight = getViewPaneSize().height, offset = winHeight * -1 + offsetTop;
- offset += (node.offsetHeight || 0);
- var elementPosition = domUtils.getXY(node);
- offset += elementPosition.y;
- var currentScroll = getScrollPosition(win).y;
- // offset += 50;
- if (offset > currentScroll || offset < currentScroll - winHeight) {
- win.scrollTo(0, offset + (offset < 0 ? -20 : 20));
- }
- },
- /**
- * 判断节点是否为br
- * @function
- * @param {Node} node 节点
- */
- isBr:function (node) {
- return node.nodeType == 1 && node.tagName == 'BR';
- },
- isFillChar:function (node,isInStart) {
- return node.nodeType == 3 && !node.nodeValue.replace(new RegExp((isInStart ? '^' : '' ) + domUtils.fillChar), '').length
- },
- isStartInblock:function (range) {
- var tmpRange = range.cloneRange(),
- flag = 0,
- start = tmpRange.startContainer,
- tmp;
- if(start.nodeType == 1 && start.childNodes[tmpRange.startOffset]){
- start = start.childNodes[tmpRange.startOffset];
- var pre = start.previousSibling;
- while(pre && domUtils.isFillChar(pre)){
- start = pre;
- pre = pre.previousSibling;
- }
- }
- if(this.isFillChar(start,true) && tmpRange.startOffset == 1){
- tmpRange.setStartBefore(start);
- start = tmpRange.startContainer;
- }
- while (start && domUtils.isFillChar(start)) {
- tmp = start;
- start = start.previousSibling
- }
- if (tmp) {
- tmpRange.setStartBefore(tmp);
- start = tmpRange.startContainer;
- }
- if (start.nodeType == 1 && domUtils.isEmptyNode(start) && tmpRange.startOffset == 1) {
- tmpRange.setStart(start, 0).collapse(true);
- }
- while (!tmpRange.startOffset) {
- start = tmpRange.startContainer;
- if (domUtils.isBlockElm(start) || domUtils.isBody(start)) {
- flag = 1;
- break;
- }
- var pre = tmpRange.startContainer.previousSibling,
- tmpNode;
- if (!pre) {
- tmpRange.setStartBefore(tmpRange.startContainer);
- } else {
- while (pre && domUtils.isFillChar(pre)) {
- tmpNode = pre;
- pre = pre.previousSibling;
- }
- if (tmpNode) {
- tmpRange.setStartBefore(tmpNode);
- } else {
- tmpRange.setStartBefore(tmpRange.startContainer);
- }
- }
- }
- return flag && !domUtils.isBody(tmpRange.startContainer) ? 1 : 0;
- },
- isEmptyBlock:function (node) {
- var reg = new RegExp('[ \t\r\n' + domUtils.fillChar + ']', 'g');
- if (node[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').length > 0) {
- return 0;
- }
- for (var n in dtd.$isNotEmpty) {
- if (node.getElementsByTagName(n).length) {
- return 0;
- }
- }
- return 1;
- },
- setViewportOffset:function (element, offset) {
- var left = parseInt(element.style.left) | 0;
- var top = parseInt(element.style.top) | 0;
- var rect = element.getBoundingClientRect();
- var offsetLeft = offset.left - rect.left;
- var offsetTop = offset.top - rect.top;
- if (offsetLeft) {
- element.style.left = left + offsetLeft + 'px';
- }
- if (offsetTop) {
- element.style.top = top + offsetTop + 'px';
- }
- },
- fillNode:function (doc, node) {
- var tmpNode = browser.ie ? doc.createTextNode(domUtils.fillChar) : doc.createElement('br');
- node.innerHTML = '';
- node.appendChild(tmpNode);
- },
- moveChild:function (src, tag, dir) {
- while (src.firstChild) {
- if (dir && tag.firstChild) {
- tag.insertBefore(src.lastChild, tag.firstChild);
- } else {
- tag.appendChild(src.firstChild);
- }
- }
- },
- //判断是否有额外属性
- hasNoAttributes:function (node) {
- return browser.ie ? /^<\w+\s*?>/.test(node.outerHTML) : node.attributes.length == 0;
- },
- //判断是否是编辑器自定义的参数
- isCustomeNode:function (node) {
- return node.nodeType == 1 && node.getAttribute('_ue_custom_node_');
- },
- isTagNode:function (node, tagName) {
- return node.nodeType == 1 && new RegExp(node.tagName,'i').test(tagName)
- },
- /**
- * 对于nodelist用filter进行过滤
- * @name filterNodeList
- * @since 1.2.4+
- * @grammar UE.dom.domUtils.filterNodeList(nodelist,filter,onlyFirst) => 节点
- * @example
- * UE.dom.domUtils.filterNodeList(document.getElementsByTagName('*'),'div p') //返回第一个是div或者p的节点
- * UE.dom.domUtils.filterNodeList(document.getElementsByTagName('*'),function(n){return n.getAttribute('src')})
- * //返回第一个带src属性的节点
- * UE.dom.domUtils.filterNodeList(document.getElementsByTagName('*'),'i',true) //返回数组,里边都是i节点
- */
- filterNodeList : function(nodelist,filter,forAll){
- var results = [];
- if(!utils .isFunction(filter)){
- var str = filter;
- filter = function(n){
- return utils.indexOf(utils.isArray(str) ? str:str.split(' '), n.tagName.toLowerCase()) != -1
- };
- }
- utils.each(nodelist,function(n){
- filter(n) && results.push(n)
- });
- return results.length == 0 ? null : results.length == 1 || !forAll ? results[0] : results
- },
- isInNodeEndBoundary : function (rng,node){
- var start = rng.startContainer;
- if(start.nodeType == 3 && rng.startOffset != start.nodeValue.length){
- return 0;
- }
- if(start.nodeType == 1 && rng.startOffset != start.childNodes.length){
- return 0;
- }
- while(start !== node){
- if(start.nextSibling){
- return 0
- };
- start = start.parentNode;
- }
- return 1;
- },
- isBoundaryNode : function (node,dir){
- var tmp;
- while(!domUtils.isBody(node)){
- tmp = node;
- node = node.parentNode;
- if(tmp !== node[dir]){
- return false;
- }
- }
- return true;
- }
- };
- var fillCharReg = new RegExp(domUtils.fillChar, 'g');
- ///import editor.js
- ///import core/utils.js
- ///import core/browser.js
- ///import core/dom/dom.js
- ///import core/dom/dtd.js
- ///import core/dom/domUtils.js
- /**
- * @file
- * @name UE.dom.Range
- * @anthor zhanyi
- * @short Range
- * @import editor.js,core/utils.js,core/browser.js,core/dom/domUtils.js,core/dom/dtd.js
- * @desc Range范围实现类,本类是UEditor底层核心类,统一w3cRange和ieRange之间的差异,包括接口和属性
- */
- (function () {
- var guid = 0,
- fillChar = domUtils.fillChar,
- fillData;
- /**
- * 更新range的collapse状态
- * @param {Range} range range对象
- */
- function updateCollapse(range) {
- range.collapsed =
- range.startContainer && range.endContainer &&
- range.startContainer === range.endContainer &&
- range.startOffset == range.endOffset;
- }
- function selectOneNode(rng){
- return !rng.collapsed && rng.startContainer.nodeType == 1 && rng.startContainer === rng.endContainer && rng.endOffset - rng.startOffset == 1
- }
- function setEndPoint(toStart, node, offset, range) {
- //如果node是自闭合标签要处理
- if (node.nodeType == 1 && (dtd.$empty[node.tagName] || dtd.$nonChild[node.tagName])) {
- offset = domUtils.getNodeIndex(node) + (toStart ? 0 : 1);
- node = node.parentNode;
- }
- if (toStart) {
- range.startContainer = node;
- range.startOffset = offset;
- if (!range.endContainer) {
- range.collapse(true);
- }
- } else {
- range.endContainer = node;
- range.endOffset = offset;
- if (!range.startContainer) {
- range.collapse(false);
- }
- }
- updateCollapse(range);
- return range;
- }
- function execContentsAction(range, action) {
- //调整边界
- //range.includeBookmark();
- var start = range.startContainer,
- end = range.endContainer,
- startOffset = range.startOffset,
- endOffset = range.endOffset,
- doc = range.document,
- frag = doc.createDocumentFragment(),
- tmpStart, tmpEnd;
- if (start.nodeType == 1) {
- start = start.childNodes[startOffset] || (tmpStart = start.appendChild(doc.createTextNode('')));
- }
- if (end.nodeType == 1) {
- end = end.childNodes[endOffset] || (tmpEnd = end.appendChild(doc.createTextNode('')));
- }
- if (start === end && start.nodeType == 3) {
- frag.appendChild(doc.createTextNode(start.substringData(startOffset, endOffset - startOffset)));
- //is not clone
- if (action) {
- start.deleteData(startOffset, endOffset - startOffset);
- range.collapse(true);
- }
- return frag;
- }
- var current, currentLevel, clone = frag,
- startParents = domUtils.findParents(start, true), endParents = domUtils.findParents(end, true);
- for (var i = 0; startParents[i] == endParents[i];) {
- i++;
- }
- for (var j = i, si; si = startParents[j]; j++) {
- current = si.nextSibling;
- if (si == start) {
- if (!tmpStart) {
- if (range.startContainer.nodeType == 3) {
- clone.appendChild(doc.createTextNode(start.nodeValue.slice(startOffset)));
- //is not clone
- if (action) {
- start.deleteData(startOffset, start.nodeValue.length - startOffset);
- }
- } else {
- clone.appendChild(!action ? start.cloneNode(true) : start);
- }
- }
- } else {
- currentLevel = si.cloneNode(false);
- clone.appendChild(currentLevel);
- }
- while (current) {
- if (current === end || current === endParents[j]) {
- break;
- }
- si = current.nextSibling;
- clone.appendChild(!action ? current.cloneNode(true) : current);
- current = si;
- }
- clone = currentLevel;
- }
- clone = frag;
- if (!startParents[i]) {
- clone.appendChild(startParents[i - 1].cloneNode(false));
- clone = clone.firstChild;
- }
- for (var j = i, ei; ei = endParents[j]; j++) {
- current = ei.previousSibling;
- if (ei == end) {
- if (!tmpEnd && range.endContainer.nodeType == 3) {
- clone.appendChild(doc.createTextNode(end.substringData(0, endOffset)));
- //is not clone
- if (action) {
- end.deleteData(0, endOffset);
- }
- }
- } else {
- currentLevel = ei.cloneNode(false);
- clone.appendChild(currentLevel);
- }
- //如果两端同级,右边第一次已经被开始做了
- if (j != i || !startParents[i]) {
- while (current) {
- if (current === start) {
- break;
- }
- ei = current.previousSibling;
- clone.insertBefore(!action ? current.cloneNode(true) : current, clone.firstChild);
- current = ei;
- }
- }
- clone = currentLevel;
- }
- if (action) {
- range.setStartBefore(!endParents[i] ? endParents[i - 1] : !startParents[i] ? startParents[i - 1] : endParents[i]).collapse(true);
- }
- tmpStart && domUtils.remove(tmpStart);
- tmpEnd && domUtils.remove(tmpEnd);
- return frag;
- }
- /**
- * @name Range
- * @grammar new UE.dom.Range(document) => Range 实例
- * @desc 创建一个跟document绑定的空的Range实例
- * - ***startContainer*** 开始边界的容器节点,可以是elementNode或者是textNode
- * - ***startOffset*** 容器节点中的偏移量,如果是elementNode就是childNodes中的第几个,如果是textNode就是nodeValue的第几个字符
- * - ***endContainer*** 结束边界的容器节点,可以是elementNode或者是textNode
- * - ***endOffset*** 容器节点中的偏移量,如果是elementNode就是childNodes中的第几个,如果是textNode就是nodeValue的第几个字符
- * - ***document*** 跟range关联的document对象
- * - ***collapsed*** 是否是闭合状态
- */
- var Range = dom.Range = function (document) {
- var me = this;
- me.startContainer =
- me.startOffset =
- me.endContainer =
- me.endOffset = null;
- me.document = document;
- me.collapsed = true;
- };
- /**
- * 删除fillData
- * @param doc
- * @param excludeNode
- */
- function removeFillData(doc, excludeNode) {
- try {
- if (fillData && domUtils.inDoc(fillData, doc)) {
- if (!fillData.nodeValue.replace(fillCharReg, '').length) {
- var tmpNode = fillData.parentNode;
- domUtils.remove(fillData);
- while (tmpNode && domUtils.isEmptyInlineElement(tmpNode) &&
- //safari的contains有bug
- (browser.safari ? !(domUtils.getPosition(tmpNode,excludeNode) & domUtils.POSITION_CONTAINS) : !tmpNode.contains(excludeNode))
- ) {
- fillData = tmpNode.parentNode;
- domUtils.remove(tmpNode);
- tmpNode = fillData;
- }
- } else {
- fillData.nodeValue = fillData.nodeValue.replace(fillCharReg, '');
- }
- }
- } catch (e) {
- }
- }
- /**
- *
- * @param node
- * @param dir
- */
- function mergeSibling(node, dir) {
- var tmpNode;
- node = node[dir];
- while (node && domUtils.isFillChar(node)) {
- tmpNode = node[dir];
- domUtils.remove(node);
- node = tmpNode;
- }
- }
- Range.prototype = {
- /**
- * @name cloneContents
- * @grammar range.cloneContents() => DocumentFragment
- * @desc 克隆选中的内容到一个fragment里,如果选区是空的将返回null
- */
- cloneContents:function () {
- return this.collapsed ? null : execContentsAction(this, 0);
- },
- /**
- * @name deleteContents
- * @grammar range.deleteContents() => Range
- * @desc 删除当前选区范围中的所有内容并返回range实例,这时的range已经变成了闭合状态
- * @example
- * DOM Element :
- * <b>x<i>x[x<i>xx]x</b>
- * //执行方法后
- * <b>x<i>x<i>|x</b>
- * 注意range改变了
- * range.startContainer => b
- * range.startOffset => 2
- * range.endContainer => b
- * range.endOffset => 2
- * range.collapsed => true
- */
- deleteContents:function () {
- var txt;
- if (!this.collapsed) {
- execContentsAction(this, 1);
- }
- if (browser.webkit) {
- txt = this.startContainer;
- if (txt.nodeType == 3 && !txt.nodeValue.length) {
- this.setStartBefore(txt).collapse(true);
- domUtils.remove(txt);
- }
- }
- return this;
- },
- /**
- * @name extractContents
- * @grammar range.extractContents() => DocumentFragment
- * @desc 将当前的内容放到一个fragment里并返回这个fragment,这时的range已经变成了闭合状态
- * @example
- * DOM Element :
- * <b>x<i>x[x<i>xx]x</b>
- * //执行方法后
- * 返回的fragment里的 dom结构是
- * <i>x<i>xx
- * dom树上的结构是
- * <b>x<i>x<i>|x</b>
- * 注意range改变了
- * range.startContainer => b
- * range.startOffset => 2
- * range.endContainer => b
- * range.endOffset => 2
- * range.collapsed => true
- */
- extractContents:function () {
- return this.collapsed ? null : execContentsAction(this, 2);
- },
- /**
- * @name setStart
- * @grammar range.setStart(node,offset) => Range
- * @desc 设置range的开始位置位于node节点内,偏移量为offset
- * 如果node是elementNode那offset指的是childNodes中的第几个,如果是textNode那offset指的是nodeValue的第几个字符
- */
- setStart:function (node, offset) {
- return setEndPoint(true, node, offset, this);
- },
- /**
- * 设置range的结束位置位于node节点,偏移量为offset
- * 如果node是elementNode那offset指的是childNodes中的第几个,如果是textNode那offset指的是nodeValue的第几个字符
- * @name setEnd
- * @grammar range.setEnd(node,offset) => Range
- */
- setEnd:function (node, offset) {
- return setEndPoint(false, node, offset, this);
- },
- /**
- * 将Range开始位置设置到node节点之后
- * @name setStartAfter
- * @grammar range.setStartAfter(node) => Range
- * @example
- * <b>xx<i>x|x</i>x</b>
- * 执行setStartAfter(i)后
- * range.startContainer =>b
- * range.startOffset =>2
- */
- setStartAfter:function (node) {
- return this.setStart(node.parentNode, domUtils.getNodeIndex(node) + 1);
- },
- /**
- * 将Range开始位置设置到node节点之前
- * @name setStartBefore
- * @grammar range.setStartBefore(node) => Range
- * @example
- * <b>xx<i>x|x</i>x</b>
- * 执行setStartBefore(i)后
- * range.startContainer =>b
- * range.startOffset =>1
- */
- setStartBefore:function (node) {
- return this.setStart(node.parentNode, domUtils.getNodeIndex(node));
- },
- /**
- * 将Range结束位置设置到node节点之后
- * @name setEndAfter
- * @grammar range.setEndAfter(node) => Range
- * @example
- * <b>xx<i>x|x</i>x</b>
- * setEndAfter(i)后
- * range.endContainer =>b
- * range.endtOffset =>2
- */
- setEndAfter:function (node) {
- return this.setEnd(node.parentNode, domUtils.getNodeIndex(node) + 1);
- },
- /**
- * 将Range结束位置设置到node节点之前
- * @name setEndBefore
- * @grammar range.setEndBefore(node) => Range
- * @example
- * <b>xx<i>x|x</i>x</b>
- * 执行setEndBefore(i)后
- * range.endContainer =>b
- * range.endtOffset =>1
- */
- setEndBefore:function (node) {
- return this.setEnd(node.parentNode, domUtils.getNodeIndex(node));
- },
- /**
- * 将Range开始位置设置到node节点内的开始位置
- * @name setStartAtFirst
- * @grammar range.setStartAtFirst(node) => Range
- */
- setStartAtFirst:function (node) {
- return this.setStart(node, 0);
- },
- /**
- * 将Range开始位置设置到node节点内的结束位置
- * @name setStartAtLast
- * @grammar range.setStartAtLast(node) => Range
- */
- setStartAtLast:function (node) {
- return this.setStart(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length);
- },
- /**
- * 将Range结束位置设置到node节点内的开始位置
- * @name setEndAtFirst
- * @grammar range.setEndAtFirst(node) => Range
- */
- setEndAtFirst:function (node) {
- return this.setEnd(node, 0);
- },
- /**
- * 将Range结束位置设置到node节点内的结束位置
- * @name setEndAtLast
- * @grammar range.setEndAtLast(node) => Range
- */
- setEndAtLast:function (node) {
- return this.setEnd(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length);
- },
- /**
- * 选中完整的指定节点,并返回包含该节点的range
- * @name selectNode
- * @grammar range.selectNode(node) => Range
- */
- selectNode:function (node) {
- return this.setStartBefore(node).setEndAfter(node);
- },
- /**
- * 选中node内部的所有节点,并返回对应的range
- * @name selectNodeContents
- * @grammar range.selectNodeContents(node) => Range
- * @example
- * <b>xx[x<i>xxx</i>]xxx</b>
- * 执行后
- * <b>[xxx<i>xxx</i>xxx]</b>
- * range.startContainer =>b
- * range.startOffset =>0
- * range.endContainer =>b
- * range.endOffset =>3
- */
- selectNodeContents:function (node) {
- return this.setStart(node, 0).setEndAtLast(node);
- },
- /**
- * 克隆一个新的range对象
- * @name cloneRange
- * @grammar range.cloneRange() => Range
- */
- cloneRange:function () {
- var me = this;
- return new Range(me.document).setStart(me.startContainer, me.startOffset).setEnd(me.endContainer, me.endOffset);
- },
- /**
- * 让选区闭合到尾部,若toStart为真,则闭合到头部
- * @name collapse
- * @grammar range.collapse() => Range
- * @grammar range.collapse(true) => Range //闭合选区到头部
- */
- collapse:function (toStart) {
- var me = this;
- if (toStart) {
- me.endContainer = me.startContainer;
- me.endOffset = me.startOffset;
- } else {
- me.startContainer = me.endContainer;
- me.startOffset = me.endOffset;
- }
- me.collapsed = true;
- return me;
- },
- /**
- * 调整range的边界,使其"收缩"到最小的位置
- * @name shrinkBoundary
- * @grammar range.shrinkBoundary() => Range //range开始位置和结束位置都调整,参见<code><a href="#adjustmentboundary">adjustmentBoundary</a></code>
- * @grammar range.shrinkBoundary(true) => Range //仅调整开始位置,忽略结束位置
- * @example
- * <b>xx[</b>xxxxx] ==> <b>xx</b>[xxxxx]
- * <b>x[xx</b><i>]xxx</i> ==> <b>x[xx]</b><i>xxx</i>
- * [<b><i>xxxx</i>xxxxxxx</b>] ==> <b><i>[xxxx</i>xxxxxxx]</b>
- */
- shrinkBoundary:function (ignoreEnd) {
- var me = this, child,
- collapsed = me.collapsed;
- function check(node){
- return node.nodeType == 1 && !domUtils.isBookmarkNode(node) && !dtd.$empty[node.tagName] && !dtd.$nonChild[node.tagName]
- }
- while (me.startContainer.nodeType == 1 //是element
- && (child = me.startContainer.childNodes[me.startOffset]) //子节点也是element
- && check(child)) {
- me.setStart(child, 0);
- }
- if (collapsed) {
- return me.collapse(true);
- }
- if (!ignoreEnd) {
- while (me.endContainer.nodeType == 1//是element
- && me.endOffset > 0 //如果是空元素就退出 endOffset=0那么endOffst-1为负值,childNodes[endOffset]报错
- && (child = me.endContainer.childNodes[me.endOffset - 1]) //子节点也是element
- && check(child)) {
- me.setEnd(child, child.childNodes.length);
- }
- }
- return me;
- },
- /**
- * 获取当前range所在位置的公共祖先节点,当前range位置可以位于文本节点内,也可以包含整个元素节点,也可以位于两个节点之间
- * @name getCommonAncestor
- * @grammar range.getCommonAncestor([includeSelf, ignoreTextNode]) => Element
- * @example
- * <b>xx[xx<i>xx]x</i>xxx</b> ==>getCommonAncestor() ==> b
- * <b>[<img/>]</b>
- * range.startContainer ==> b
- * range.startOffset ==> 0
- * range.endContainer ==> b
- * range.endOffset ==> 1
- * range.getCommonAncestor() ==> b
- * range.getCommonAncestor(true) ==> img
- * <b>xxx|xx</b>
- * range.startContainer ==> textNode
- * range.startOffset ==> 3
- * range.endContainer ==> textNode
- * range.endOffset ==> 3
- * range.getCommonAncestor() ==> textNode
- * range.getCommonAncestor(null,true) ==> b
- */
- getCommonAncestor:function (includeSelf, ignoreTextNode) {
- var me = this,
- start = me.startContainer,
- end = me.endContainer;
- if (start === end) {
- if (includeSelf && selectOneNode(this)) {
- start = start.childNodes[me.startOffset];
- if(start.nodeType == 1)
- return start;
- }
- //只有在上来就相等的情况下才会出现是文本的情况
- return ignoreTextNode && start.nodeType == 3 ? start.parentNode : start;
- }
- return domUtils.getCommonAncestor(start, end);
- },
- /**
- * 调整边界容器,如果是textNode,就调整到elementNode上
- * @name trimBoundary
- * @grammar range.trimBoundary([ignoreEnd]) => Range //true忽略结束边界
- * @example
- * DOM Element :
- * <b>|xxx</b>
- * startContainer = xxx; startOffset = 0
- * //执行后本方法后
- * startContainer = <b>; startOffset = 0
- * @example
- * Dom Element :
- * <b>xx|x</b>
- * startContainer = xxx; startOffset = 2
- * //执行本方法后,xxx被实实在在地切分成两个TextNode
- * startContainer = <b>; startOffset = 1
- */
- trimBoundary:function (ignoreEnd) {
- this.txtToElmBoundary();
- var start = this.startContainer,
- offset = this.startOffset,
- collapsed = this.collapsed,
- end = this.endContainer;
- if (start.nodeType == 3) {
- if (offset == 0) {
- this.setStartBefore(start);
- } else {
- if (offset >= start.nodeValue.length) {
- this.setStartAfter(start);
- } else {
- var textNode = domUtils.split(start, offset);
- //跟新结束边界
- if (start === end) {
- this.setEnd(textNode, this.endOffset - offset);
- } else if (start.parentNode === end) {
- this.endOffset += 1;
- }
- this.setStartBefore(textNode);
- }
- }
- if (collapsed) {
- return this.collapse(true);
- }
- }
- if (!ignoreEnd) {
- offset = this.endOffset;
- end = this.endContainer;
- if (end.nodeType == 3) {
- if (offset == 0) {
- this.setEndBefore(end);
- } else {
- offset < end.nodeValue.length && domUtils.split(end, offset);
- this.setEndAfter(end);
- }
- }
- }
- return this;
- },
- /**
- * 如果选区在文本的边界上,就扩展选区到文本的父节点上
- * @name txtToElmBoundary
- * @example
- * Dom Element :
- * <b> |xxx</b>
- * startContainer = xxx; startOffset = 0
- * //本方法执行后
- * startContainer = <b>; startOffset = 0
- * @example
- * Dom Element :
- * <b> xxx| </b>
- * startContainer = xxx; startOffset = 3
- * //本方法执行后
- * startContainer = <b>; startOffset = 1
- */
- txtToElmBoundary:function () {
- function adjust(r, c) {
- var container = r[c + 'Container'],
- offset = r[c + 'Offset'];
- if (container.nodeType == 3) {
- if (!offset) {
- r['set' + c.replace(/(\w)/, function (a) {
- return a.toUpperCase();
- }) + 'Before'](container);
- } else if (offset >= container.nodeValue.length) {
- r['set' + c.replace(/(\w)/, function (a) {
- return a.toUpperCase();
- }) + 'After' ](container);
- }
- }
- }
- if (!this.collapsed) {
- adjust(this, 'start');
- adjust(this, 'end');
- }
- return this;
- },
- /**
- * 在当前选区的开始位置前插入一个节点或者fragment,range的开始位置会在插入节点的前边
- * @name insertNode
- * @grammar range.insertNode(node) => Range //node可以是textNode,elementNode,fragment
- * @example
- * Range :
- * xxx[x<p>xxxx</p>xxxx]x<p>sdfsdf</p>
- * 待插入Node :
- * <p>ssss</p>
- * 执行本方法后的Range :
- * xxx[<p>ssss</p>x<p>xxxx</p>xxxx]x<p>sdfsdf</p>
- */
- insertNode:function (node) {
- var first = node, length = 1;
- if (node.nodeType == 11) {
- first = node.firstChild;
- length = node.childNodes.length;
- }
- this.trimBoundary(true);
- var start = this.startContainer,
- offset = this.startOffset;
- var nextNode = start.childNodes[ offset ];
- if (nextNode) {
- start.insertBefore(node, nextNode);
- } else {
- start.appendChild(node);
- }
- if (first.parentNode === this.endContainer) {
- this.endOffset = this.endOffset + length;
- }
- return this.setStartBefore(first);
- },
- /**
- * 设置光标闭合位置,toEnd设置为true时光标将闭合到选区的结尾
- * @name setCursor
- * @grammar range.setCursor([toEnd]) => Range //toEnd为true时,光标闭合到选区的末尾
- */
- setCursor:function (toEnd, noFillData) {
- return this.collapse(!toEnd).select(noFillData);
- },
- /**
- * 创建当前range的一个书签,记录下当前range的位置,方便当dom树改变时,还能找回原来的选区位置
- * @name createBookmark
- * @grammar range.createBookmark([serialize]) => Object //{start:开始标记,end:结束标记,id:serialize} serialize为真时,开始结束标记是插入节点的id,否则是插入节点的引用
- */
- createBookmark:function (serialize, same) {
- var endNode,
- startNode = this.document.createElement('span');
- startNode.style.cssText = 'display:none;line-height:0px;';
- startNode.appendChild(this.document.createTextNode('\u200D'));
- startNode.id = '_baidu_bookmark_start_' + (same ? '' : guid++);
- if (!this.collapsed) {
- endNode = startNode.cloneNode(true);
- endNode.id = '_baidu_bookmark_end_' + (same ? '' : guid++);
- }
- this.insertNode(startNode);
- if (endNode) {
- this.collapse().insertNode(endNode).setEndBefore(endNode);
- }
- this.setStartAfter(startNode);
- return {
- start:serialize ? startNode.id : startNode,
- end:endNode ? serialize ? endNode.id : endNode : null,
- id:serialize
- }
- },
- /**
- * 移动边界到书签位置,并删除插入的书签节点
- * @name moveToBookmark
- * @grammar range.moveToBookmark(bookmark) => Range //让当前的range选到给定bookmark的位置,bookmark对象是由range.createBookmark创建的
- */
- moveToBookmark:function (bookmark) {
- var start = bookmark.id ? this.document.getElementById(bookmark.start) : bookmark.start,
- end = bookmark.end && bookmark.id ? this.document.getElementById(bookmark.end) : bookmark.end;
- this.setStartBefore(start);
- domUtils.remove(start);
- if (end) {
- this.setEndBefore(end);
- domUtils.remove(end);
- } else {
- this.collapse(true);
- }
- return this;
- },
- /**
- * 调整range的边界,使其"放大"到最近的父block节点
- * @name enlarge
- * @grammar range.enlarge() => Range
- * @example
- * <p><span>xxx</span><b>x[x</b>xxxxx]</p><p>xxx</p> ==> [<p><span>xxx</span><b>xx</b>xxxxx</p>]<p>xxx</p>
- */
- enlarge:function (toBlock, stopFn) {
- var isBody = domUtils.isBody,
- pre, node, tmp = this.document.createTextNode('');
- if (toBlock) {
- node = this.startContainer;
- if (node.nodeType == 1) {
- if (node.childNodes[this.startOffset]) {
- pre = node = node.childNodes[this.startOffset]
- } else {
- node.appendChild(tmp);
- pre = node = tmp;
- }
- } else {
- pre = node;
- }
- while (1) {
- if (domUtils.isBlockElm(node)) {
- node = pre;
- while ((pre = node.previousSibling) && !domUtils.isBlockElm(pre)) {
- node = pre;
- }
- this.setStartBefore(node);
- break;
- }
- pre = node;
- node = node.parentNode;
- }
- node = this.endContainer;
- if (node.nodeType == 1) {
- if (pre = node.childNodes[this.endOffset]) {
- node.insertBefore(tmp, pre);
- } else {
- node.appendChild(tmp);
- }
- pre = node = tmp;
- } else {
- pre = node;
- }
- while (1) {
- if (domUtils.isBlockElm(node)) {
- node = pre;
- while ((pre = node.nextSibling) && !domUtils.isBlockElm(pre)) {
- node = pre;
- }
- this.setEndAfter(node);
- break;
- }
- pre = node;
- node = node.parentNode;
- }
- if (tmp.parentNode === this.endContainer) {
- this.endOffset--;
- }
- domUtils.remove(tmp);
- }
- // 扩展边界到最大
- if (!this.collapsed) {
- while (this.startOffset == 0) {
- if (stopFn && stopFn(this.startContainer)) {
- break;
- }
- if (isBody(this.startContainer)) {
- break;
- }
- this.setStartBefore(this.startContainer);
- }
- while (this.endOffset == (this.endContainer.nodeType == 1 ? this.endContainer.childNodes.length : this.endContainer.nodeValue.length)) {
- if (stopFn && stopFn(this.endContainer)) {
- break;
- }
- if (isBody(this.endContainer)) {
- break;
- }
- this.setEndAfter(this.endContainer);
- }
- }
- return this;
- },
- /**
- * 调整Range的边界,使其"缩小"到最合适的位置
- * @name adjustmentBoundary
- * @grammar range.adjustmentBoundary() => Range //参见<code><a href="#shrinkboundary">shrinkBoundary</a></code>
- * @example
- * <b>xx[</b>xxxxx] ==> <b>xx</b>[xxxxx]
- * <b>x[xx</b><i>]xxx</i> ==> <b>x[xx</b>]<i>xxx</i>
- */
- adjustmentBoundary:function () {
- if (!this.collapsed) {
- while (!domUtils.isBody(this.startContainer) &&
- this.startOffset == this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length
- ) {
- this.setStartAfter(this.startContainer);
- }
- while (!domUtils.isBody(this.endContainer) && !this.endOffset) {
- this.setEndBefore(this.endContainer);
- }
- }
- return this;
- },
- /**
- * 给range选区中的内容添加给定的标签,主要用于inline标签
- * @name applyInlineStyle
- * @grammar range.applyInlineStyle(tagName) => Range //tagName为需要添加的样式标签名
- * @grammar range.applyInlineStyle(tagName,attrs) => Range //attrs为属性json对象
- * @desc
- * <code type="html"><p>xxxx[xxxx]x</p> ==> range.applyInlineStyle("strong") ==> <p>xxxx[<strong>xxxx</strong>]x</p>
- * <p>xx[dd<strong>yyyy</strong>]x</p> ==> range.applyInlineStyle("strong") ==> <p>xx[<strong>ddyyyy</strong>]x</p>
- * <p>xxxx[xxxx]x</p> ==> range.applyInlineStyle("strong",{"style":"font-size:12px"}) ==> <p>xxxx[<strong style="font-size:12px">xxxx</strong>]x</p></code>
- */
- applyInlineStyle:function (tagName, attrs, list) {
- if (this.collapsed)return this;
- this.trimBoundary().enlarge(false,
- function (node) {
- return node.nodeType == 1 && domUtils.isBlockElm(node)
- }).adjustmentBoundary();
- var bookmark = this.createBookmark(),
- end = bookmark.end,
- filterFn = function (node) {
- return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node);
- },
- current = domUtils.getNextDomNode(bookmark.start, false, filterFn),
- node,
- pre,
- range = this.cloneRange();
- while (current && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) {
- if (current.nodeType == 3 || dtd[tagName][current.tagName]) {
- range.setStartBefore(current);
- node = current;
- while (node && (node.nodeType == 3 || dtd[tagName][node.tagName]) && node !== end) {
- pre = node;
- node = domUtils.getNextDomNode(node, node.nodeType == 1, null, function (parent) {
- return dtd[tagName][parent.tagName];
- });
- }
- var frag = range.setEndAfter(pre).extractContents(), elm;
- if (list && list.length > 0) {
- var level, top;
- top = level = list[0].cloneNode(false);
- for (var i = 1, ci; ci = list[i++];) {
- level.appendChild(ci.cloneNode(false));
- level = level.firstChild;
- }
- elm = level;
- } else {
- elm = range.document.createElement(tagName);
- }
- if (attrs) {
- domUtils.setAttributes(elm, attrs);
- }
- elm.appendChild(frag);
- range.insertNode(list ? top : elm);
- //处理下滑线在a上的情况
- var aNode;
- if (tagName == 'span' && attrs.style && /text\-decoration/.test(attrs.style) && (aNode = domUtils.findParentByTagName(elm, 'a', true))) {
- domUtils.setAttributes(aNode, attrs);
- domUtils.remove(elm, true);
- elm = aNode;
- } else {
- domUtils.mergeSibling(elm);
- domUtils.clearEmptySibling(elm);
- }
- //去除子节点相同的
- domUtils.mergeChild(elm, attrs);
- current = domUtils.getNextDomNode(elm, false, filterFn);
- domUtils.mergeToParent(elm);
- if (node === end) {
- break;
- }
- } else {
- current = domUtils.getNextDomNode(current, true, filterFn);
- }
- }
- return this.moveToBookmark(bookmark);
- },
- /**
- * 对当前range选中的节点,去掉给定的标签节点,但标签中的内容保留,主要用于处理inline元素
- * @name removeInlineStyle
- * @grammar range.removeInlineStyle(tagNames) => Range //tagNames 为需要去掉的样式标签名,支持"b"或者["b","i","u"]
- * @desc
- * <code type="html">xx[x<span>xxx<em>yyy</em>zz]z</span> => range.removeInlineStyle(["em"]) => xx[x<span>xxxyyyzz]z</span></code>
- */
- removeInlineStyle:function (tagNames) {
- if (this.collapsed)return this;
- tagNames = utils.isArray(tagNames) ? tagNames : [tagNames];
- this.shrinkBoundary().adjustmentBoundary();
- var start = this.startContainer, end = this.endContainer;
- while (1) {
- if (start.nodeType == 1) {
- if (utils.indexOf(tagNames, start.tagName.toLowerCase()) > -1) {
- break;
- }
- if (start.tagName.toLowerCase() == 'body') {
- start = null;
- break;
- }
- }
- start = start.parentNode;
- }
- while (1) {
- if (end.nodeType == 1) {
- if (utils.indexOf(tagNames, end.tagName.toLowerCase()) > -1) {
- break;
- }
- if (end.tagName.toLowerCase() == 'body') {
- end = null;
- break;
- }
- }
- end = end.parentNode;
- }
- var bookmark = this.createBookmark(),
- frag,
- tmpRange;
- if (start) {
- tmpRange = this.cloneRange().setEndBefore(bookmark.start).setStartBefore(start);
- frag = tmpRange.extractContents();
- tmpRange.insertNode(frag);
- domUtils.clearEmptySibling(start, true);
- start.parentNode.insertBefore(bookmark.start, start);
- }
- if (end) {
- tmpRange = this.cloneRange().setStartAfter(bookmark.end).setEndAfter(end);
- frag = tmpRange.extractContents();
- tmpRange.insertNode(frag);
- domUtils.clearEmptySibling(end, false, true);
- end.parentNode.insertBefore(bookmark.end, end.nextSibling);
- }
- var current = domUtils.getNextDomNode(bookmark.start, false, function (node) {
- return node.nodeType == 1;
- }), next;
- while (current && current !== bookmark.end) {
- next = domUtils.getNextDomNode(current, true, function (node) {
- return node.nodeType == 1;
- });
- if (utils.indexOf(tagNames, current.tagName.toLowerCase()) > -1) {
- domUtils.remove(current, true);
- }
- current = next;
- }
- return this.moveToBookmark(bookmark);
- },
- /**
- * 得到一个自闭合的节点,常用于获取自闭和的节点,例如图片节点
- * @name getClosedNode
- * @grammar range.getClosedNode() => node|null
- * @example
- * <b>xxxx[<img />]xxx</b>
- */
- getClosedNode:function () {
- var node;
- if (!this.collapsed) {
- var range = this.cloneRange().adjustmentBoundary().shrinkBoundary();
- if (selectOneNode(range)) {
- var child = range.startContainer.childNodes[range.startOffset];
- if (child && child.nodeType == 1 && (dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName])) {
- node = child;
- }
- }
- }
- return node;
- },
- /**
- * 根据当前range选中内容节点(在页面上表现为反白显示)
- * @name select
- * @grammar range.select(); => Range
- */
- select:browser.ie ? function (noFillData, textRange) {
- var nativeRange;
- if (!this.collapsed)
- this.shrinkBoundary();
- var node = this.getClosedNode();
- if (node && !textRange) {
- try {
- nativeRange = this.document.body.createControlRange();
- nativeRange.addElement(node);
- nativeRange.select();
- } catch (e) {}
- return this;
- }
- var bookmark = this.createBookmark(),
- start = bookmark.start,
- end;
- nativeRange = this.document.body.createTextRange();
- nativeRange.moveToElementText(start);
- nativeRange.moveStart('character', 1);
- if (!this.collapsed) {
- var nativeRangeEnd = this.document.body.createTextRange();
- end = bookmark.end;
- nativeRangeEnd.moveToElementText(end);
- nativeRange.setEndPoint('EndToEnd', nativeRangeEnd);
- } else {
- if (!noFillData && this.startContainer.nodeType != 3) {
- //使用<span>|x<span>固定住光标
- var tmpText = this.document.createTextNode(fillChar),
- tmp = this.document.createElement('span');
- tmp.appendChild(this.document.createTextNode(fillChar));
- start.parentNode.insertBefore(tmp, start);
- start.parentNode.insertBefore(tmpText, start);
- //当点b,i,u时,不能清除i上边的b
- removeFillData(this.document, tmpText);
- fillData = tmpText;
- mergeSibling(tmp, 'previousSibling');
- mergeSibling(start, 'nextSibling');
- nativeRange.moveStart('character', -1);
- nativeRange.collapse(true);
- }
- }
- this.moveToBookmark(bookmark);
- tmp && domUtils.remove(tmp);
- //IE在隐藏状态下不支持range操作,catch一下
- try {
- nativeRange.select();
- } catch (e) {
- }
- return this;
- } : function (notInsertFillData) {
- function checkOffset(rng){
- function check(node,offset,dir){
- if(node.nodeType == 3 && node.nodeValue.length < offset){
- rng[dir + 'Offset'] = node.nodeValue.length
- }
- }
- check(rng.startContainer,rng.startOffset,'start');
- check(rng.endContainer,rng.endOffset,'end');
- }
- var win = domUtils.getWindow(this.document),
- sel = win.getSelection(),
- txtNode;
- //FF下关闭自动长高时滚动条在关闭dialog时会跳
- //ff下如果不body.focus将不能定位闭合光标到编辑器内
- browser.gecko ? this.document.body.focus() : win.focus();
- if (sel) {
- sel.removeAllRanges();
- // trace:870 chrome/safari后边是br对于闭合得range不能定位 所以去掉了判断
- // this.startContainer.nodeType != 3 &&! ((child = this.startContainer.childNodes[this.startOffset]) && child.nodeType == 1 && child.tagName == 'BR'
- if (this.collapsed && !notInsertFillData) {
- // //opear如果没有节点接着,原生的不能够定位,不能在body的第一级插入空白节点
- // if (notInsertFillData && browser.opera && !domUtils.isBody(this.startContainer) && this.startContainer.nodeType == 1) {
- // var tmp = this.document.createTextNode('');
- // this.insertNode(tmp).setStart(tmp, 0).collapse(true);
- // }
- //
- //处理光标落在文本节点的情况
- //处理以下的情况
- //<b>|xxxx</b>
- //<b>xxxx</b>|xxxx
- //xxxx<b>|</b>
- var start = this.startContainer,child = start;
- if(start.nodeType == 1){
- child = start.childNodes[this.startOffset];
- }
- if( !(start.nodeType == 3 && this.startOffset) &&
- (child ?
- (!child.previousSibling || child.previousSibling.nodeType != 3)
- :
- (!start.lastChild || start.lastChild.nodeType != 3)
- )
- ){
- txtNode = this.document.createTextNode(fillChar);
- //跟着前边走
- this.insertNode(txtNode);
- removeFillData(this.document, txtNode);
- mergeSibling(txtNode, 'previousSibling');
- mergeSibling(txtNode, 'nextSibling');
- fillData = txtNode;
- this.setStart(txtNode, browser.webkit ? 1 : 0).collapse(true);
- }
- }
- var nativeRange = this.document.createRange();
- if(this.collapsed && browser.opera && this.startContainer.nodeType == 1){
- var child = this.startContainer.childNodes[this.startOffset];
- if(!child){
- //往前靠拢
- child = this.startContainer.lastChild;
- if( child && domUtils.isBr(child)){
- this.setStartBefore(child).collapse(true);
- }
- }else{
- //向后靠拢
- while(child && domUtils.isBlockElm(child)){
- if(child.nodeType == 1 && child.childNodes[0]){
- child = child.childNodes[0]
- }else{
- break;
- }
- }
- child && this.setStartBefore(child).collapse(true)
- }
- }
- //是createAddress最后一位算的不准,现在这里进行微调
- checkOffset(this);
- nativeRange.setStart(this.startContainer, this.startOffset);
- nativeRange.setEnd(this.endContainer, this.endOffset);
- sel.addRange(nativeRange);
- }
- return this;
- },
- /**
- * 滚动条跳到当然range开始的位置
- * @name scrollToView
- * @grammar range.scrollToView([win,offset]) => Range //针对window对象,若不指定,将以编辑区域的窗口为准,offset偏移量
- */
- scrollToView:function (win, offset) {
- win = win ? window : domUtils.getWindow(this.document);
- var me = this,
- span = me.document.createElement('span');
- //trace:717
- span.innerHTML = ' ';
- me.cloneRange().insertNode(span);
- domUtils.scrollToView(span, win, offset);
- domUtils.remove(span);
- return me;
- },
- inFillChar : function(){
- var start = this.startContainer;
- if(this.collapsed && start.nodeType == 3
- && start.nodeValue.replace(new RegExp('^' + domUtils.fillChar),'').length + 1 == start.nodeValue.length
- ){
- return true;
- }
- return false;
- },
- createAddress : function(ignoreEnd,ignoreTxt){
- var addr = {},me = this;
- function getAddress(isStart){
- var node = isStart ? me.startContainer : me.endContainer;
- var parents = domUtils.findParents(node,true,function(node){return !domUtils.isBody(node)}),
- addrs = [];
- for(var i = 0,ci;ci = parents[i++];){
- addrs.push(domUtils.getNodeIndex(ci,ignoreTxt));
- }
- var firstIndex = 0;
- if(ignoreTxt){
- if(node.nodeType == 3){
- var tmpNode = node;
- while(tmpNode = tmpNode.previousSibling){
- if(tmpNode.nodeType == 3){
- firstIndex += tmpNode.nodeValue.replace(fillCharReg,'').length;
- }else{
- break;
- }
- }
- firstIndex += (isStart ? me.startOffset : me.endOffset) - (fillCharReg.test(node.nodeValue) ? 1 : 0 )
- }else{
- node = node.childNodes[ isStart ? me.startOffset : me.endOffset];
- if(node){
- firstIndex = domUtils.getNodeIndex(node,ignoreTxt);
- }else{
- node = isStart ? me.startContainer : me.endContainer;
- var first = node.firstChild;
- while(first){
- if(domUtils.isFillChar(first)){
- first = first.nextSibling;
- continue;
- }
- firstIndex++;
- if(first.nodeType == 3){
- while( first && first.nodeType == 3){
- first = first.nextSibling;
- }
- }else{
- first = first.nextSibling;
- }
- }
- }
- }
- }else{
- firstIndex = isStart ? me.startOffset : me.endOffset
- }
- if(firstIndex < 0){
- firstIndex = 0;
- }
- addrs.push(firstIndex);
- return addrs;
- }
- addr.startAddress = getAddress(true);
- if(!ignoreEnd){
- addr.endAddress = me.collapsed ? [].concat(addr.startAddress) : getAddress();
- }
- return addr;
- },
- moveToAddress : function(addr,ignoreEnd){
- var me = this;
- function getNode(address,isStart){
- var tmpNode = me.document.body,
- parentNode,offset;
- for(var i= 0,ci,l=address.length;i<l;i++){
- ci = address[i];
- parentNode = tmpNode;
- tmpNode = tmpNode.childNodes[ci];
- if(!tmpNode){
- offset = ci;
- break;
- }
- }
- if(isStart){
- if(tmpNode){
- me.setStartBefore(tmpNode)
- }else{
- me.setStart(parentNode,offset)
- }
- }else{
- if(tmpNode){
- me.setEndBefore(tmpNode)
- }else{
- me.setEnd(parentNode,offset)
- }
- }
- }
- getNode(addr.startAddress,true);
- !ignoreEnd && addr.endAddress && getNode(addr.endAddress);
- return me;
- },
- equals : function(rng){
- for(var p in this){
- if(this.hasOwnProperty(p)){
- if(this[p] !== rng[p])
- return false
- }
- }
- return true;
- }
- };
- })();
- ///import editor.js
- ///import core/browser.js
- ///import core/dom/dom.js
- ///import core/dom/dtd.js
- ///import core/dom/domUtils.js
- ///import core/dom/Range.js
- /**
- * @class baidu.editor.dom.Selection Selection类
- */
- (function () {
- function getBoundaryInformation( range, start ) {
- var getIndex = domUtils.getNodeIndex;
- range = range.duplicate();
- range.collapse( start );
- var parent = range.parentElement();
- //如果节点里没有子节点,直接退出
- if ( !parent.hasChildNodes() ) {
- return {container:parent, offset:0};
- }
- var siblings = parent.children,
- child,
- testRange = range.duplicate(),
- startIndex = 0, endIndex = siblings.length - 1, index = -1,
- distance;
- while ( startIndex <= endIndex ) {
- index = Math.floor( (startIndex + endIndex) / 2 );
- child = siblings[index];
- testRange.moveToElementText( child );
- var position = testRange.compareEndPoints( 'StartToStart', range );
- if ( position > 0 ) {
- endIndex = index - 1;
- } else if ( position < 0 ) {
- startIndex = index + 1;
- } else {
- //trace:1043
- return {container:parent, offset:getIndex( child )};
- }
- }
- if ( index == -1 ) {
- testRange.moveToElementText( parent );
- testRange.setEndPoint( 'StartToStart', range );
- distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
- siblings = parent.childNodes;
- if ( !distance ) {
- child = siblings[siblings.length - 1];
- return {container:child, offset:child.nodeValue.length};
- }
- var i = siblings.length;
- while ( distance > 0 ){
- distance -= siblings[ --i ].nodeValue.length;
- }
- return {container:siblings[i], offset:-distance};
- }
- testRange.collapse( position > 0 );
- testRange.setEndPoint( position > 0 ? 'StartToStart' : 'EndToStart', range );
- distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
- if ( !distance ) {
- return dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName] ?
- {container:parent, offset:getIndex( child ) + (position > 0 ? 0 : 1)} :
- {container:child, offset:position > 0 ? 0 : child.childNodes.length}
- }
- while ( distance > 0 ) {
- try {
- var pre = child;
- child = child[position > 0 ? 'previousSibling' : 'nextSibling'];
- distance -= child.nodeValue.length;
- } catch ( e ) {
- return {container:parent, offset:getIndex( pre )};
- }
- }
- return {container:child, offset:position > 0 ? -distance : child.nodeValue.length + distance}
- }
- /**
- * 将ieRange转换为Range对象
- * @param {Range} ieRange ieRange对象
- * @param {Range} range Range对象
- * @return {Range} range 返回转换后的Range对象
- */
- function transformIERangeToRange( ieRange, range ) {
- if ( ieRange.item ) {
- range.selectNode( ieRange.item( 0 ) );
- } else {
- var bi = getBoundaryInformation( ieRange, true );
- range.setStart( bi.container, bi.offset );
- if ( ieRange.compareEndPoints( 'StartToEnd', ieRange ) != 0 ) {
- bi = getBoundaryInformation( ieRange, false );
- range.setEnd( bi.container, bi.offset );
- }
- }
- return range;
- }
- /**
- * 获得ieRange
- * @param {Selection} sel Selection对象
- * @return {ieRange} 得到ieRange
- */
- function _getIERange( sel ) {
- var ieRange;
- //ie下有可能报错
- try {
- ieRange = sel.getNative().createRange();
- } catch ( e ) {
- return null;
- }
- var el = ieRange.item ? ieRange.item( 0 ) : ieRange.parentElement();
- if ( ( el.ownerDocument || el ) === sel.document ) {
- return ieRange;
- }
- return null;
- }
- var Selection = dom.Selection = function ( doc ) {
- var me = this, iframe;
- me.document = doc;
- if ( ie ) {
- iframe = domUtils.getWindow( doc ).frameElement;
- domUtils.on( iframe, 'beforedeactivate', function () {
- me._bakIERange = me.getIERange();
- } );
- domUtils.on( iframe, 'activate', function () {
- try {
- if ( !_getIERange( me ) && me._bakIERange ) {
- me._bakIERange.select();
- }
- } catch ( ex ) {
- }
- me._bakIERange = null;
- } );
- }
- iframe = doc = null;
- };
- Selection.prototype = {
- /**
- * 获取原生seleciton对象
- * @public
- * @function
- * @name baidu.editor.dom.Selection.getNative
- * @return {Selection} 获得selection对象
- */
- getNative:function () {
- var doc = this.document;
- try {
- return !doc ? null : ie ? doc.selection : domUtils.getWindow( doc ).getSelection();
- } catch ( e ) {
- return null;
- }
- },
- /**
- * 获得ieRange
- * @public
- * @function
- * @name baidu.editor.dom.Selection.getIERange
- * @return {ieRange} 返回ie原生的Range
- */
- getIERange:function () {
- var ieRange = _getIERange( this );
- if ( !ieRange ) {
- if ( this._bakIERange ) {
- return this._bakIERange;
- }
- }
- return ieRange;
- },
- /**
- * 缓存当前选区的range和选区的开始节点
- * @public
- * @function
- * @name baidu.editor.dom.Selection.cache
- */
- cache:function () {
- this.clear();
- this._cachedRange = this.getRange();
- this._cachedStartElement = this.getStart();
- this._cachedStartElementPath = this.getStartElementPath();
- },
- getStartElementPath:function () {
- if ( this._cachedStartElementPath ) {
- return this._cachedStartElementPath;
- }
- var start = this.getStart();
- if ( start ) {
- return domUtils.findParents( start, true, null, true )
- }
- return [];
- },
- /**
- * 清空缓存
- * @public
- * @function
- * @name baidu.editor.dom.Selection.clear
- */
- clear:function () {
- this._cachedStartElementPath = this._cachedRange = this._cachedStartElement = null;
- },
- /**
- * 编辑器是否得到了选区
- */
- isFocus:function () {
- try {
- return browser.ie && _getIERange( this ) || !browser.ie && this.getNative().rangeCount ? true : false;
- } catch ( e ) {
- return false;
- }
- },
- /**
- * 获取选区对应的Range
- * @public
- * @function
- * @name baidu.editor.dom.Selection.getRange
- * @returns {baidu.editor.dom.Range} 得到Range对象
- */
- getRange:function () {
- var me = this;
- function optimze( range ) {
- var child = me.document.body.firstChild,
- collapsed = range.collapsed;
- while ( child && child.firstChild ) {
- range.setStart( child, 0 );
- child = child.firstChild;
- }
- if ( !range.startContainer ) {
- range.setStart( me.document.body, 0 )
- }
- if ( collapsed ) {
- range.collapse( true );
- }
- }
- if ( me._cachedRange != null ) {
- return this._cachedRange;
- }
- var range = new baidu.editor.dom.Range( me.document );
- if ( ie ) {
- var nativeRange = me.getIERange();
- if ( nativeRange ) {
- //备份的_bakIERange可能已经实效了,dom树发生了变化比如从源码模式切回来,所以try一下,实效就放到body开始位置
- try{
- transformIERangeToRange( nativeRange, range );
- }catch(e){
- optimze( range );
- }
- } else {
- optimze( range );
- }
- } else {
- var sel = me.getNative();
- if ( sel && sel.rangeCount ) {
- var firstRange = sel.getRangeAt( 0 );
- var lastRange = sel.getRangeAt( sel.rangeCount - 1 );
- range.setStart( firstRange.startContainer, firstRange.startOffset ).setEnd( lastRange.endContainer, lastRange.endOffset );
- if ( range.collapsed && domUtils.isBody( range.startContainer ) && !range.startOffset ) {
- optimze( range );
- }
- } else {
- //trace:1734 有可能已经不在dom树上了,标识的节点
- if ( this._bakRange && domUtils.inDoc( this._bakRange.startContainer, this.document ) ){
- return this._bakRange;
- }
- optimze( range );
- }
- }
- return this._bakRange = range;
- },
- /**
- * 获取开始元素,用于状态反射
- * @public
- * @function
- * @name baidu.editor.dom.Selection.getStart
- * @return {Element} 获得开始元素
- */
- getStart:function () {
- if ( this._cachedStartElement ) {
- return this._cachedStartElement;
- }
- var range = ie ? this.getIERange() : this.getRange(),
- tmpRange,
- start, tmp, parent;
- if ( ie ) {
- if ( !range ) {
- //todo 给第一个值可能会有问题
- return this.document.body.firstChild;
- }
- //control元素
- if ( range.item ){
- return range.item( 0 );
- }
- tmpRange = range.duplicate();
- //修正ie下<b>x</b>[xx] 闭合后 <b>x|</b>xx
- tmpRange.text.length > 0 && tmpRange.moveStart( 'character', 1 );
- tmpRange.collapse( 1 );
- start = tmpRange.parentElement();
- parent = tmp = range.parentElement();
- while ( tmp = tmp.parentNode ) {
- if ( tmp == start ) {
- start = parent;
- break;
- }
- }
- } else {
- range.shrinkBoundary();
- start = range.startContainer;
- if ( start.nodeType == 1 && start.hasChildNodes() ){
- start = start.childNodes[Math.min( start.childNodes.length - 1, range.startOffset )];
- }
- if ( start.nodeType == 3 ){
- return start.parentNode;
- }
- }
- return start;
- },
- /**
- * 得到选区中的文本
- * @public
- * @function
- * @name baidu.editor.dom.Selection.getText
- * @return {String} 选区中包含的文本
- */
- getText:function () {
- var nativeSel, nativeRange;
- if ( this.isFocus() && (nativeSel = this.getNative()) ) {
- nativeRange = browser.ie ? nativeSel.createRange() : nativeSel.getRangeAt( 0 );
- return browser.ie ? nativeRange.text : nativeRange.toString();
- }
- return '';
- },
- clearRange : function(){
- this.getNative()[browser.ie ? 'empty' : 'removeAllRanges']();
- }
- };
- })();
- /**
- * @file
- * @name UE.Editor
- * @short Editor
- * @import editor.js,core/utils.js,core/EventBase.js,core/browser.js,core/dom/dtd.js,core/dom/domUtils.js,core/dom/Range.js,core/dom/Selection.js,plugins/serialize.js
- * @desc 编辑器主类,包含编辑器提供的大部分公用接口
- */
- (function () {
- var uid = 0,_selectionChangeTimer;
- /**
- * 替换src和href
- * @private
- * @ignore
- * @param div
- */
- function replaceSrc( div ) {
- var imgs = div.getElementsByTagName( "img" ),
- orgSrc;
- for ( var i = 0, img; img = imgs[i++]; ) {
- if ( orgSrc = img.getAttribute( "orgSrc" ) ) {
- img.src = orgSrc;
- img.removeAttribute( "orgSrc" );
- }
- }
- var as = div.getElementsByTagName( "a" );
- for ( var i = 0, ai; ai = as[i++]; i++ ) {
- if ( ai.getAttribute( 'data_ue_src' ) ) {
- ai.setAttribute( 'href', ai.getAttribute( 'data_ue_src' ) )
- }
- }
- }
- /**
- * @private
- * @ignore
- * @param form 编辑器所在的form元素
- * @param editor 编辑器实例对象
- */
- function setValue( form, editor ) {
- var textarea;
- if ( editor.textarea ) {
- if ( utils.isString( editor.textarea ) ) {
- for ( var i = 0, ti, tis = domUtils.getElementsByTagName( form, 'textarea' ); ti = tis[i++]; ) {
- if ( ti.id == 'ueditor_textarea_' + editor.options.textarea ) {
- textarea = ti;
- break;
- }
- }
- } else {
- textarea = editor.textarea;
- }
- }
- if ( !textarea ) {
- form.appendChild( textarea = domUtils.createElement( document, 'textarea', {
- 'name':editor.options.textarea,
- 'id':'ueditor_textarea_' + editor.options.textarea,
- 'style':"display:none"
- } ) );
- //不要产生多个textarea
- editor.textarea = textarea;
- }
- textarea.value = editor.hasContents() ?
- (editor.options.allHtmlEnabled ? editor.getAllHtml() : editor.getContent(null,null,true)):
- ''
- }
- /**
- * UEditor编辑器类
- * @name Editor
- * @desc 创建一个跟编辑器实例
- * - ***container*** 编辑器容器对象
- * - ***iframe*** 编辑区域所在的iframe对象
- * - ***window*** 编辑区域所在的window
- * - ***document*** 编辑区域所在的document对象
- * - ***body*** 编辑区域所在的body对象
- * - ***selection*** 编辑区域的选区对象
- */
- var Editor = UE.Editor = function ( options ) {
- var me = this;
- me.uid = uid++;
- EventBase.call( me );
- me.commands = {};
- me.options = utils.extend( utils.clone(options || {}),UEDITOR_CONFIG, true );
- me.shortcutkeys = {};
- //设置默认的常用属性
- me.setOpt( {
- isShow:true,
- initialContent:'欢迎使用ueditor!',
- autoClearinitialContent:false,
- iframeCssUrl:me.options.UEDITOR_HOME_URL + 'themes/iframe.css',
- textarea:'editorValue',
- focus:false,
- initialFrameWidth:1000,
- initialFrameHeight:me.options.minFrameHeight||320,//兼容老版本配置项
- minFrameWidth:800,
- minFrameHeight:220,
- autoClearEmptyNode:true,
- fullscreen:false,
- readonly:false,
- zIndex:999,
- imagePopup:true,
- enterTag:'p',
- pageBreakTag:'_baidu_page_break_tag_',
- customDomain:false,
- lang:'zh-cn',
- langPath:me.options.UEDITOR_HOME_URL + 'lang/',
- theme:'default',
- themePath:me.options.UEDITOR_HOME_URL + 'themes/',
- allHtmlEnabled:false,
- scaleEnabled:false,
- tableNativeEditInFF:false
- } );
- utils.loadFile( document, {
- src:me.options.langPath + me.options.lang + "/" + me.options.lang + ".js",
- tag:"script",
- type:"text/javascript",
- defer:"defer"
- }, function () {
- //初始化插件
- for ( var pi in UE.plugins ) {
- UE.plugins[pi].call( me );
- }
- me.langIsReady = true;
- me.fireEvent( "langReady" );
- });
- UE.instants['ueditorInstant' + me.uid] = me;
- };
- Editor.prototype = {
- /**
- * 当编辑器ready后执行传入的fn,如果编辑器已经完成ready,就马上执行fn,fn的中的this是编辑器实例。
- * 大部分的实例接口都需要放在该方法内部执行,否则在IE下可能会报错。
- * @name ready
- * @grammar editor.ready(fn) fn是当编辑器渲染好后执行的function
- * @example
- * var editor = new UE.ui.Editor();
- * editor.render("myEditor");
- * editor.ready(function(){
- * editor.setContent("欢迎使用UEditor!");
- * })
- */
- ready:function ( fn ) {
- var me = this;
- if ( fn ){
- me.isReady ? fn.apply( me ) : me.addListener( 'ready', fn );
- }
- },
- /**
- * 为编辑器设置默认参数值。若用户配置为空,则以默认配置为准
- * @grammar editor.setOpt(key,value); //传入一个键、值对
- * @grammar editor.setOpt({ key:value}); //传入一个json对象
- */
- setOpt:function ( key, val ) {
- var obj = {};
- if ( utils.isString( key ) ) {
- obj[key] = val
- } else {
- obj = key;
- }
- utils.extend( this.options, obj, true );
- },
- /**
- * 销毁编辑器实例对象
- * @name destroy
- * @grammar editor.destroy();
- */
- destroy:function () {
- var me = this;
- me.fireEvent( 'destroy' );
- var container = me.container.parentNode;
- var textarea = me.textarea;
- if(!textarea){
- textarea = document.createElement('textarea');
- container.parentNode.insertBefore(textarea,container);
- }else{
- textarea.style.display = ''
- }
- textarea.style.width = container.offsetWidth + 'px';
- textarea.style.height = container.offsetHeight + 'px';
- textarea.value = me.getContent();
- textarea.id = me.key;
- container.innerHTML = '';
- domUtils.remove( container );
- var key = me.key;
- //trace:2004
- for ( var p in me ) {
- if ( me.hasOwnProperty( p ) ) {
- delete this[p];
- }
- }
- UE.delEditor(key);
- },
- /**
- * 渲染编辑器的DOM到指定容器,必须且只能调用一次
- * @name render
- * @grammar editor.render(containerId); //可以指定一个容器ID
- * @grammar editor.render(containerDom); //也可以直接指定容器对象
- */
- render:function ( container ) {
- var me = this, options = me.options;
- if ( utils.isString(container) ) {
- container = document.getElementById( container );
- }
- if ( container ) {
- var useBodyAsViewport = ie && browser.version < 9,
- html = ( ie && browser.version < 9 ? '' : '<!DOCTYPE html>') +
- '<html xmlns=\'http://www.w3.org/1999/xhtml\'' + (!useBodyAsViewport ? ' class=\'view\'' : '') + '><head>' +
- ( options.iframeCssUrl ? '<link rel=\'stylesheet\' type=\'text/css\' href=\'' + utils.unhtml( options.iframeCssUrl ) + '\'/>' : '' ) +
- '<style type=\'text/css\'>' +
- //设置四周的留边
- '.view{padding:0;word-wrap:break-word;cursor:text;height:100%;}\n' +
- //设置默认字体和字号
- //font-family不能呢随便改,在safari下fillchar会有解析问题
- 'body{margin:8px;font-family:sans-serif;font-size:16px;}' +
- //设置段落间距
- 'p{margin:5px 0;}'
- + ( options.initialStyle || '' ) +
- '</style></head><body' + (useBodyAsViewport ? ' class=\'view\'' : '') + '></body>';
- if ( options.customDomain && document.domain != location.hostname ) {
- html += '<script>window.parent.UE.instants[\'ueditorInstant' + me.uid + '\']._setup(document);</script></html>';
- container.appendChild( domUtils.createElement( document, 'iframe', {
- id:'baidu_editor_' + me.uid,
- width:"100%",
- height:"100%",
- frameborder:"0",
- src:'javascript:void(function(){document.open();document.domain="' + document.domain + '";' +
- 'document.write("' + html + '");document.close();}())'
- } ) );
- } else {
- container.innerHTML = '<iframe id="' + 'baidu_editor_' + this.uid + '"' + 'width="100%" height="100%" scroll="no" frameborder="0" ></iframe>';
- var doc = container.firstChild.contentWindow.document;
- //去掉了原来的判断!browser.webkit,因为会导致onload注册的事件不触发
- doc.open();
- doc.write( html + '</html>' );
- doc.close();
- me._setup( doc );
- }
- container.style.overflow = 'hidden';
- }
- },
- /**
- * 编辑器初始化
- * @private
- * @ignore
- * @param {Element} doc 编辑器Iframe中的文档对象
- */
- _setup:function ( doc ) {
- var me = this,
- options = me.options;
- if ( ie ) {
- doc.body.disabled = true;
- doc.body.contentEditable = true;
- doc.body.disabled = false;
- } else {
- doc.body.contentEditable = true;
- doc.body.spellcheck = false;
- }
- me.document = doc;
- me.window = doc.defaultView || doc.parentWindow;
- me.iframe = me.window.frameElement;
- me.body = doc.body;
- //设置编辑器最小高度
- me.setHeight( Math.max(options.minFrameHeight, options.initialFrameHeight));
- me.selection = new dom.Selection( doc );
- //gecko初始化就能得到range,无法判断isFocus了
- var geckoSel;
- if ( browser.gecko && (geckoSel = this.selection.getNative()) ) {
- geckoSel.removeAllRanges();
- }
- this._initEvents();
- if ( options.initialContent ) {
- if ( options.autoClearinitialContent ) {
- var oldExecCommand = me.execCommand;
- me.execCommand = function () {
- me.fireEvent( 'firstBeforeExecCommand' );
- return oldExecCommand.apply( me, arguments );
- };
- this._setDefaultContent( options.initialContent );
- } else
- this.setContent( options.initialContent, false,true );
- }
- //为form提交提供一个隐藏的textarea
- for ( var form = this.iframe.parentNode; !domUtils.isBody( form ); form = form.parentNode ) {
- if ( form.tagName == 'FORM' ) {
- domUtils.on( form, 'submit', function () {
- setValue( this, me );
- } );
- break;
- }
- }
- //编辑器不能为空内容
- if ( domUtils.isEmptyNode( me.body ) ) {
- me.body.innerHTML = '<p>' + (browser.ie ? '' : '<br/>') + '</p>';
- }
- //如果要求focus, 就把光标定位到内容开始
- if ( options.focus ) {
- setTimeout( function () {
- me.focus();
- //如果自动清除开着,就不需要做selectionchange;
- !me.options.autoClearinitialContent && me._selectionChange();
- },0);
- }
- if ( !me.container ) {
- me.container = this.iframe.parentNode;
- }
- if ( options.fullscreen && me.ui ) {
- me.ui.setFullScreen( true );
- }
- try {
- me.document.execCommand( '2D-position', false, false );
- } catch ( e ) {}
- try {
- me.document.execCommand( 'enableInlineTableEditing', false, false );
- } catch ( e ) {}
- try {
- me.document.execCommand( 'enableObjectResizing', false, false );
- } catch ( e ) {
- // domUtils.on(me.body,browser.ie ? 'resizestart' : 'resize', function( evt ) {
- // domUtils.preventDefault(evt)
- // });
- }
- me._bindshortcutKeys();
- me.isReady = 1;
- me.fireEvent( 'ready' );
- options.onready && options.onready.call(me);
- if ( !browser.ie ) {
- domUtils.on( me.window, ['blur', 'focus'], function ( e ) {
- //chrome下会出现alt+tab切换时,导致选区位置不对
- if ( e.type == 'blur' ) {
- me._bakRange = me.selection.getRange();
- try{
- me.selection.getNative().removeAllRanges();
- }catch(e){}
- } else {
- try {
- me._bakRange && me._bakRange.select();
- } catch ( e ) {
- }
- }
- } );
- }
- //trace:1518 ff3.6body不够寛,会导致点击空白处无法获得焦点
- if ( browser.gecko && browser.version <= 10902 ) {
- //修复ff3.6初始化进来,不能点击获得焦点
- me.body.contentEditable = false;
- setTimeout( function () {
- me.body.contentEditable = true;
- }, 100 );
- setInterval( function () {
- me.body.style.height = me.iframe.offsetHeight - 20 + 'px'
- }, 100 )
- }
- !options.isShow && me.setHide();
- options.readonly && me.setDisabled();
- },
- /**
- * 同步编辑器的数据,为提交数据做准备,主要用于你是手动提交的情况
- * @name sync
- * @grammar editor.sync(); //从编辑器的容器向上查找,如果找到就同步数据
- * @grammar editor.sync(formID); //formID制定一个要同步数据的form的id,编辑器的数据会同步到你指定form下
- * @desc
- * 后台取得数据得键值使用你容器上得''name''属性,如果没有就使用参数传入的''textarea''
- * @example
- * editor.sync();
- * form.sumbit(); //form变量已经指向了form元素
- *
- */
- sync:function ( formId ) {
- var me = this,
- form = formId ? document.getElementById( formId ) :
- domUtils.findParent( me.iframe.parentNode, function ( node ) {
- return node.tagName == 'FORM'
- }, true );
- form && setValue( form, me );
- },
- /**
- * 设置编辑器高度
- * @name setHeight
- * @grammar editor.setHeight(number); //纯数值,不带单位
- */
- setHeight:function ( height ) {
- if ( height !== parseInt( this.iframe.parentNode.style.height ) ) {
- this.iframe.parentNode.style.height = height + 'px';
- }
- this.document.body.style.height = height - 20 + 'px';
- },
- addshortcutkey : function(cmd,keys){
- var obj = {};
- if(keys){
- obj[cmd] = keys
- }else{
- obj = cmd;
- }
- utils.extend(this.shortcutkeys,obj)
- },
- _bindshortcutKeys : function(){
- var me = this,shortcutkeys = this.shortcutkeys;
- me.addListener('keydown',function(type,e){
- var keyCode = e.keyCode || e.which;
- for ( var i in shortcutkeys ) {
- var tmp = shortcutkeys[i].split(',');
- for(var t= 0,ti;ti=tmp[t++];){
- ti = ti.split(':');
- var key = ti[0],param = ti[1];
- if ( /^(ctrl)(\+shift)?\+(\d+)$/.test( key.toLowerCase() ) || /^(\d+)$/.test( key ) ) {
- if ( ( (RegExp.$1 == 'ctrl' ? (e.ctrlKey||e.metaKey) : 0)
- && (RegExp.$2 != "" ? e[RegExp.$2.slice(1) + "Key"] : 1)
- && keyCode == RegExp.$3
- ) ||
- keyCode == RegExp.$1
- ){
- me.execCommand(i,param);
- domUtils.preventDefault(e);
- }
- }
- }
- }
- });
- },
- /**
- * 获取编辑器内容
- * @name getContent
- * @grammar editor.getContent() => String //若编辑器中只包含字符"<p><br /></p/>"会返回空。
- * @grammar editor.getContent(fn) => String
- * @example
- * getContent默认是会现调用hasContents来判断编辑器是否为空,如果是,就直接返回空字符串
- * 你也可以传入一个fn来接替hasContents的工作,定制判断的规则
- * editor.getContent(function(){
- * return false //编辑器没有内容 ,getContent直接返回空
- * })
- */
- getContent:function ( cmd, fn, isPreview ,notSetCursor) {
- var me = this;
- if ( cmd && utils.isFunction( cmd ) ) {
- fn = cmd;
- cmd = '';
- }
- if ( fn ? !fn() : !this.hasContents() ) {
- return '';
- }
- var range = me.selection.getRange(),
- address = range.createAddress();
- me.fireEvent( 'beforegetcontent', cmd );
- var reg = new RegExp( domUtils.fillChar, 'g' ),
- //ie下取得的html可能会有\n存在,要去掉,在处理replace(/[\t\r\n]*/g,'');代码高量的\n不能去除
- html = me.body.innerHTML.replace( reg, '' ).replace( />[\t\r\n]*?</g, '><' );
- me.fireEvent( 'aftergetcontent', cmd );
- try{
- !notSetCursor && range.moveToAddress(address).select(true);
- }catch(e){}
- if ( me.serialize ) {
- var node = me.serialize.parseHTML( html );
- node = me.serialize.transformOutput( node );
- html = me.serialize.toHTML( node );
- }
- if ( ie && isPreview ) {
- //trace:2471
- //两个br会导致空行,所以这里先注视掉
- html = html//.replace(/<\s*br\s*\/?\s*>/gi,'<br/><br/>')
- .replace( /<p>\s*?<\/p>/g, '<p> </p>' );
- } else {
- //多个 要转换成空格加 的形式,要不预览时会所成一个
- html = html.replace( /( )+/g, function ( s ) {
- for ( var i = 0, str = [], l = s.split( ';' ).length - 1; i < l; i++ ) {
- str.push( i % 2 == 0 ? ' ' : ' ' );
- }
- return str.join( '' );
- } );
- }
- return html;
- },
- /**
- * 取得完整的html代码,可以直接显示成完整的html文档
- * @name getAllHtml
- * @grammar editor.getAllHtml() => String
- */
- getAllHtml:function () {
- var me = this,
- headHtml = [],
- html = '';
- me.fireEvent( 'getAllHtml', headHtml );
- if(browser.ie && browser.version > 8){
- var headHtmlForIE9= '';
- utils.each(me.document.styleSheets,function(si){
- headHtmlForIE9 += ( si.href ? '<link rel="stylesheet" type="text/css" href="'+si.href+'" />': '<style>'+si.cssText+'</style>');
- });
- utils.each(me.document.getElementsByTagName('script'),function(si){
- headHtmlForIE9 += si.outerHTML;
- });
- }
- return '<html><head>' + (me.options.charset ? '<meta http-equiv="Content-Type" content="text/html; charset=' + me.options.charset + '"/>' : '')
- + (headHtmlForIE9 || me.document.getElementsByTagName( 'head' )[0].innerHTML) + headHtml.join('\n') + '</head>'
- + '<body ' + (ie && browser.version < 9 ? 'class="view"' : '') + '>' + me.getContent( null, null, true ) + '</body></html>';
- },
- /**
- * 得到编辑器的纯文本内容,但会保留段落格式
- * @name getPlainTxt
- * @grammar editor.getPlainTxt() => String
- */
- getPlainTxt:function () {
- var reg = new RegExp( domUtils.fillChar, 'g' ),
- html = this.body.innerHTML.replace( /[\n\r]/g, '' );//ie要先去了\n在处理
- html = html.replace( /<(p|div)[^>]*>(<br\/?>| )<\/\1>/gi, '\n' )
- .replace( /<br\/?>/gi, '\n' )
- .replace( /<[^>/]+>/g, '' )
- .replace( /(\n)?<\/([^>]+)>/g, function ( a, b, c ) {
- return dtd.$block[c] ? '\n' : b ? b : '';
- } );
- //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0
- return html.replace( reg, '' ).replace( /\u00a0/g, ' ' ).replace( / /g, ' ' );
- },
- /**
- * 获取编辑器中的纯文本内容,没有段落格式
- * @name getContentTxt
- * @grammar editor.getContentTxt() => String
- */
- getContentTxt:function () {
- var reg = new RegExp( domUtils.fillChar, 'g' );
- //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0
- return this.body[browser.ie ? 'innerText' : 'textContent'].replace( reg, '' ).replace( /\u00a0/g, ' ' );
- },
- /**
- * 将html设置到编辑器中, 如果是用于初始化时给编辑器赋初值,则必须放在ready方法内部执行
- * @name setContent
- * @grammar editor.setContent(html)
- * @example
- * var editor = new UE.ui.Editor()
- * editor.ready(function(){
- * //需要ready后执行,否则可能报错
- * editor.setContent("欢迎使用UEditor!");
- * })
- */
- setContent:function ( html, isAppendTo,notFireSelectionchange ) {
- var me = this,
- inline = utils.extend( {a:1, A:1}, dtd.$inline, true ),
- lastTagName;
- html = html
- .replace( /^[ \t\r\n]*?</, '<' )
- .replace( />[ \t\r\n]*?$/, '>' )
- //ie有时的源码会有> <的情况
- .replace(/>(?:(\s| )*?)</g,'><' )//代码高量的\n不能去除
- .replace( /[\s\/]?(\w+)?>[ \t\r\n]*?<\/?(\w+)/gi, function ( a, b, c ) {
- if ( b ) {
- lastTagName = c;
- } else {
- b = lastTagName;
- }
- return !inline[b] && !inline[c] ? a.replace( />[ \t\r\n]*?</, '><' ) : a;
- } );
- html = {'html':html};
- me.fireEvent( 'beforesetcontent',html );
- html = html.html;
- var serialize = this.serialize;
- if ( serialize ) {
- var node = serialize.parseHTML( html );
- node = serialize.transformInput( node );
- node = serialize.filter( node );
- html = serialize.toHTML( node );
- }
- //html.replace(new RegExp('[\t\n\r' + domUtils.fillChar + ']*','g'),'');
- //去掉了\t\n\r 如果有插入的代码,在源码切换所见即所得模式时,换行都丢掉了
- //\r在ie下的不可见字符,在源码切换时会变成多个
- //trace:1559
- this.body.innerHTML = (isAppendTo ? this.getContent() : '') + html.replace( new RegExp( '[\r' + domUtils.fillChar + ']*', 'g' ), '' );
- //处理ie6下innerHTML自动将相对路径转化成绝对路径的问题
- if ( browser.ie && browser.version < 7 ) {
- replaceSrc( this.document.body );
- }
- //给文本或者inline节点套p标签
- if ( me.options.enterTag == 'p' ) {
- var child = this.body.firstChild, tmpNode;
- if ( !child || child.nodeType == 1 &&
- (dtd.$cdata[child.tagName] ||
- domUtils.isCustomeNode( child )
- )
- && child === this.body.lastChild ) {
- this.body.innerHTML = '<p>' + (browser.ie ? ' ' : '<br/>') + '</p>' + this.body.innerHTML;
- } else {
- var p = me.document.createElement( 'p' );
- while ( child ) {
- while ( child && (child.nodeType == 3 || child.nodeType == 1 && dtd.p[child.tagName] && !dtd.$cdata[child.tagName]) ) {
- tmpNode = child.nextSibling;
- p.appendChild( child );
- child = tmpNode;
- }
- if ( p.firstChild ) {
- if ( !child ) {
- me.body.appendChild( p );
- break;
- } else {
- child.parentNode.insertBefore( p, child );
- p = me.document.createElement( 'p' );
- }
- }
- child = child.nextSibling;
- }
- }
- }
- me.fireEvent( 'aftersetcontent' );
- me.fireEvent( 'contentchange' );
- !notFireSelectionchange && me._selectionChange();
- //清除保存的选区
- me._bakRange = me._bakIERange = null;
- //trace:1742 setContent后gecko能得到焦点问题
- var geckoSel;
- if ( browser.gecko && (geckoSel = this.selection.getNative()) ) {
- geckoSel.removeAllRanges();
- }
- },
- /**
- * 让编辑器获得焦点,toEnd确定focus位置
- * @name focus
- * @grammar editor.focus([toEnd]) //默认focus到编辑器头部,toEnd为true时focus到内容尾部
- */
- focus:function ( toEnd ) {
- try {
- var me = this,
- rng = me.selection.getRange();
- if ( toEnd ) {
- rng.setStartAtLast( me.body.lastChild ).setCursor( false, true );
- } else {
- rng.select( true );
- }
- } catch ( e ) {
- }
- },
- /**
- * 初始化UE事件及部分事件代理
- * @private
- * @ignore
- */
- _initEvents:function () {
- var me = this,
- doc = me.document,
- win = me.window;
- me._proxyDomEvent = utils.bind( me._proxyDomEvent, me );
- domUtils.on( doc, ['click', 'contextmenu', 'mousedown', 'keydown', 'keyup', 'keypress', 'mouseup', 'mouseover', 'mouseout', 'selectstart'], me._proxyDomEvent );
- domUtils.on( win, ['focus', 'blur'], me._proxyDomEvent );
- domUtils.on( doc, ['mouseup', 'keydown'], function ( evt ) {
- //特殊键不触发selectionchange
- if ( evt.type == 'keydown' && (evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey) ) {
- return;
- }
- if ( evt.button == 2 )return;
- me._selectionChange( 250, evt );
- } );
- //处理拖拽
- //ie ff不能从外边拖入
- //chrome只针对从外边拖入的内容过滤
- var innerDrag = 0, source = browser.ie ? me.body : me.document, dragoverHandler;
- domUtils.on( source, 'dragstart', function () {
- innerDrag = 1;
- } );
- domUtils.on( source, browser.webkit ? 'dragover' : 'drop', function () {
- return browser.webkit ?
- function () {
- clearTimeout( dragoverHandler );
- dragoverHandler = setTimeout( function () {
- if ( !innerDrag ) {
- var sel = me.selection,
- range = sel.getRange();
- if ( range ) {
- var common = range.getCommonAncestor();
- if ( common && me.serialize ) {
- var f = me.serialize,
- node =
- f.filter(
- f.transformInput(
- f.parseHTML(
- f.word( common.innerHTML )
- )
- )
- );
- common.innerHTML = f.toHTML( node );
- }
- }
- }
- innerDrag = 0;
- }, 200 );
- } :
- function ( e ) {
- if ( !innerDrag ) {
- e.preventDefault ? e.preventDefault() : (e.returnValue = false);
- }
- innerDrag = 0;
- }
- }() );
- },
- /**
- * 触发事件代理
- * @private
- * @ignore
- */
- _proxyDomEvent:function ( evt ) {
- return this.fireEvent( evt.type.replace( /^on/, '' ), evt );
- },
- /**
- * 变化选区
- * @private
- * @ignore
- */
- _selectionChange:function ( delay, evt ) {
- var me = this;
- //有光标才做selectionchange 为了解决未focus时点击source不能触发更改工具栏状态的问题(source命令notNeedUndo=1)
- // if ( !me.selection.isFocus() ){
- // return;
- // }
- var hackForMouseUp = false;
- var mouseX, mouseY;
- if ( browser.ie && browser.version < 9 && evt && evt.type == 'mouseup' ) {
- var range = this.selection.getRange();
- if ( !range.collapsed ) {
- hackForMouseUp = true;
- mouseX = evt.clientX;
- mouseY = evt.clientY;
- }
- }
- clearTimeout( _selectionChangeTimer );
- _selectionChangeTimer = setTimeout( function () {
- if ( !me.selection.getNative() ) {
- return;
- }
- //修复一个IE下的bug: 鼠标点击一段已选择的文本中间时,可能在mouseup后的一段时间内取到的range是在selection的type为None下的错误值.
- //IE下如果用户是拖拽一段已选择文本,则不会触发mouseup事件,所以这里的特殊处理不会对其有影响
- var ieRange;
- if ( hackForMouseUp && me.selection.getNative().type == 'None' ) {
- ieRange = me.document.body.createTextRange();
- try {
- ieRange.moveToPoint( mouseX, mouseY );
- } catch ( ex ) {
- ieRange = null;
- }
- }
- var bakGetIERange;
- if ( ieRange ) {
- bakGetIERange = me.selection.getIERange;
- me.selection.getIERange = function () {
- return ieRange;
- };
- }
- me.selection.cache();
- if ( bakGetIERange ) {
- me.selection.getIERange = bakGetIERange;
- }
- if ( me.selection._cachedRange && me.selection._cachedStartElement ) {
- me.fireEvent( 'beforeselectionchange' );
- // 第二个参数causeByUi为true代表由用户交互造成的selectionchange.
- me.fireEvent( 'selectionchange', !!evt );
- me.fireEvent( 'afterselectionchange' );
- me.selection.clear();
- }
- }, delay || 50 );
- },
- _callCmdFn:function ( fnName, args ) {
- var cmdName = args[0].toLowerCase(),
- cmd, cmdFn;
- cmd = this.commands[cmdName] || UE.commands[cmdName];
- cmdFn = cmd && cmd[fnName];
- //没有querycommandstate或者没有command的都默认返回0
- if ( (!cmd || !cmdFn) && fnName == 'queryCommandState' ) {
- return 0;
- } else if ( cmdFn ) {
- return cmdFn.apply( this, args );
- }
- },
- /**
- * 执行编辑命令cmdName,完成富文本编辑效果
- * @name execCommand
- * @grammar editor.execCommand(cmdName) => {*}
- */
- execCommand:function ( cmdName ) {
- cmdName = cmdName.toLowerCase();
- var me = this,
- result,
- cmd = me.commands[cmdName] || UE.commands[cmdName];
- if ( !cmd || !cmd.execCommand ) {
- return null;
- }
- if ( !cmd.notNeedUndo && !me.__hasEnterExecCommand ) {
- me.__hasEnterExecCommand = true;
- if ( me.queryCommandState( cmdName ) != -1 ) {
- me.fireEvent( 'beforeexeccommand', cmdName );
- result = this._callCmdFn( 'execCommand', arguments );
- !me._ignoreContentChange && me.fireEvent('contentchange');
- me.fireEvent( 'afterexeccommand', cmdName );
- }
- me.__hasEnterExecCommand = false;
- } else {
- result = this._callCmdFn( 'execCommand', arguments );
- !me._ignoreContentChange && me.fireEvent('contentchange')
- }
- !me._ignoreContentChange && me._selectionChange();
- return result;
- },
- /**
- * 根据传入的command命令,查选编辑器当前的选区,返回命令的状态
- * @name queryCommandState
- * @grammar editor.queryCommandState(cmdName) => (-1|0|1)
- * @desc
- * * ''-1'' 当前命令不可用
- * * ''0'' 当前命令可用
- * * ''1'' 当前命令已经执行过了
- */
- queryCommandState:function ( cmdName ) {
- return this._callCmdFn( 'queryCommandState', arguments );
- },
- /**
- * 根据传入的command命令,查选编辑器当前的选区,根据命令返回相关的值
- * @name queryCommandValue
- * @grammar editor.queryCommandValue(cmdName) => {*}
- */
- queryCommandValue:function ( cmdName ) {
- return this._callCmdFn( 'queryCommandValue', arguments );
- },
- /**
- * 检查编辑区域中是否有内容,若包含tags中的节点类型,直接返回true
- * @name hasContents
- * @desc
- * 默认有文本内容,或者有以下节点都不认为是空
- * <code>{table:1,ul:1,ol:1,dl:1,iframe:1,area:1,base:1,col:1,hr:1,img:1,embed:1,input:1,link:1,meta:1,param:1}</code>
- * @grammar editor.hasContents() => (true|false)
- * @grammar editor.hasContents(tags) => (true|false) //若文档中包含tags数组里对应的tag,直接返回true
- * @example
- * editor.hasContents(['span']) //如果编辑器里有这些,不认为是空
- */
- hasContents:function ( tags ) {
- if ( tags ) {
- for ( var i = 0, ci; ci = tags[i++]; ) {
- if ( this.document.getElementsByTagName( ci ).length > 0 ) {
- return true;
- }
- }
- }
- if ( !domUtils.isEmptyBlock( this.body ) ) {
- return true
- }
- //随时添加,定义的特殊标签如果存在,不能认为是空
- tags = ['div'];
- for ( i = 0; ci = tags[i++]; ) {
- var nodes = domUtils.getElementsByTagName( this.document, ci );
- for ( var n = 0, cn; cn = nodes[n++]; ) {
- if ( domUtils.isCustomeNode( cn ) ) {
- return true;
- }
- }
- }
- return false;
- },
- /**
- * 重置编辑器,可用来做多个tab使用同一个编辑器实例
- * @name reset
- * @desc
- * * 清空编辑器内容
- * * 清空回退列表
- * @grammar editor.reset()
- */
- reset:function () {
- this.fireEvent( 'reset' );
- },
- setEnabled:function () {
- var me = this, range;
- if ( me.body.contentEditable == 'false' ) {
- me.body.contentEditable = true;
- range = me.selection.getRange();
- //有可能内容丢失了
- try {
- range.moveToBookmark( me.lastBk );
- delete me.lastBk
- } catch ( e ) {
- range.setStartAtFirst( me.body ).collapse( true )
- }
- range.select( true );
- if ( me.bkqueryCommandState ) {
- me.queryCommandState = me.bkqueryCommandState;
- delete me.bkqueryCommandState;
- }
- me.fireEvent( 'selectionchange' );
- }
- },
- /**
- * 设置当前编辑区域可以编辑
- * @name enable
- * @grammar editor.enable()
- */
- enable:function(){
- return this.setEnabled();
- },
- setDisabled:function ( except ) {
- var me = this;
- except = except ? utils.isArray( except ) ? except : [except] : [];
- if ( me.body.contentEditable == 'true' ) {
- if ( !me.lastBk ) {
- me.lastBk = me.selection.getRange().createBookmark( true );
- }
- me.body.contentEditable = false;
- me.bkqueryCommandState = me.queryCommandState;
- me.queryCommandState = function ( type ) {
- if ( utils.indexOf( except, type ) != -1 ) {
- return me.bkqueryCommandState.apply( me, arguments );
- }
- return -1;
- };
- me.fireEvent( 'selectionchange' );
- }
- },
- /** 设置当前编辑区域不可编辑,except中的命令除外
- * @name disable
- * @grammar editor.disable()
- * @grammar editor.disable(except) //例外的命令,也即即使设置了disable,此处配置的命令仍然可以执行
- * @example
- * //禁用工具栏中除加粗和插入图片之外的所有功能
- * editor.disable(['bold','insertimage']);//可以是单一的String,也可以是Array
- */
- disable:function(except){
- return this.setDisabled(except);
- },
- /**
- * 设置默认内容
- * @ignore
- * @private
- * @param {String} cont 要存入的内容
- */
- _setDefaultContent:function () {
- function clear() {
- var me = this;
- if ( me.document.getElementById( 'initContent' ) ) {
- me.body.innerHTML = '<p>' + (ie ? '' : '<br/>') + '</p>';
- me.removeListener( 'firstBeforeExecCommand focus', clear );
- setTimeout( function () {
- me.focus();
- me._selectionChange();
- },0 )
- }
- }
- return function ( cont ) {
- var me = this;
- me.body.innerHTML = '<p id="initContent">' + cont + '</p>';
- if ( browser.ie && browser.version < 7 ) {
- replaceSrc( me.body );
- }
- me.addListener( 'firstBeforeExecCommand focus', clear );
- }
- }(),
- /**
- * show方法的兼容版本
- * @private
- * @ignore
- */
- setShow:function () {
- var me = this,range = me.selection.getRange();
- if ( me.container.style.display == 'none' ) {
- //有可能内容丢失了
- try {
- range.moveToBookmark( me.lastBk );
- delete me.lastBk
- } catch ( e ) {
- range.setStartAtFirst( me.body ).collapse( true )
- }
- //ie下focus实效,所以做了个延迟
- setTimeout(function(){
- range.select( true );
- },100);
- me.container.style.display = '';
- }
- },
- /**
- * 显示编辑器
- * @name show
- * @grammar editor.show()
- */
- show:function(){
- return this.setShow();
- },
- /**
- * hide方法的兼容版本
- * @private
- * @ignore
- */
- setHide:function () {
- var me = this;
- if ( !me.lastBk ) {
- me.lastBk = me.selection.getRange().createBookmark( true );
- }
- me.container.style.display = 'none'
- },
- /**
- * 隐藏编辑器
- * @name hide
- * @grammar editor.hide()
- */
- hide:function(){
- return this.setHide();
- },
- /**
- * 根据制定的路径,获取对应的语言资源
- * @name getLang
- * @grammar editor.getLang(path) => (JSON|String) 路径根据的是lang目录下的语言文件的路径结构
- * @example
- * editor.getLang('contextMenu.delete') //如果当前是中文,那返回是的是删除
- */
- getLang:function ( path ) {
- var lang = UE.I18N[this.options.lang];
- if(!lang){
- throw Error("not import language file");
- }
- path = (path || "").split( "." );
- for ( var i = 0, ci; ci = path[i++]; ) {
- lang = lang[ci];
- if ( !lang )break;
- }
- return lang;
- },
- /**
- * 计算编辑器当前内容的长度
- * @name getContentLength
- * @grammar editor.getContentLength(ingoneHtml,tagNames) =>
- * @example
- * editor.getLang(true)
- */
- getContentLength : function(ingoneHtml,tagNames){
- var count = this.getContent(false,false,false,true).length;
- if(ingoneHtml){
- tagNames = (tagNames||[]).concat([ 'hr','img','iframe']);
- count = this.getContentTxt().replace(/[\t\r\n]+/g,'').length;
- for(var i= 0,ci;ci=tagNames[i++];){
- count += this.document.getElementsByTagName(ci).length;
- }
- }
- return count;
- }
- /**
- * 得到dialog实例对象
- * @name getDialog
- * @grammar editor.getDialog(dialogName) => Object
- * @example
- * var dialog = editor.getDialog("insertimage");
- * dialog.open(); //打开dialog
- * dialog.close(); //关闭dialog
- */
- };
- utils.inherits( Editor, EventBase );
- })();
- /**
- * @file
- * @name UE.ajax
- * @short Ajax
- * @desc UEditor内置的ajax请求模块
- * @import core/utils.js
- * @user: taoqili
- * @date: 11-8-18
- * @time: 下午3:18
- */
- UE.ajax = function() {
- /**
- * 创建一个ajaxRequest对象
- */
- var fnStr = 'XMLHttpRequest()';
- try {
- new ActiveXObject("Msxml2.XMLHTTP");
- fnStr = 'ActiveXObject(\'Msxml2.XMLHTTP\')';
- } catch (e) {
- try {
- new ActiveXObject("Microsoft.XMLHTTP");
- fnStr = 'ActiveXObject(\'Microsoft.XMLHTTP\')'
- } catch (e) {
- }
- }
- var creatAjaxRequest = new Function('return new ' + fnStr);
- /**
- * 将json参数转化成适合ajax提交的参数列表
- * @param json
- */
- function json2str(json) {
- var strArr = [];
- for (var i in json) {
- //忽略默认的几个参数
- if(i=="method" || i=="timeout" || i=="async") continue;
- //传递过来的对象和函数不在提交之列
- if (!((typeof json[i]).toLowerCase() == "function" || (typeof json[i]).toLowerCase() == "object")) {
- strArr.push( encodeURIComponent(i) + "="+encodeURIComponent(json[i]) );
- }
- }
- return strArr.join("&");
- }
- return {
- /**
- * @name request
- * @desc 发出ajax请求,ajaxOpt中默认包含method,timeout,async,data,onsuccess以及onerror等六个,支持自定义添加参数
- * @grammar UE.ajax.request(url,ajaxOpt);
- * @example
- * UE.ajax.request('http://www.xxxx.com/test.php',{
- * //可省略,默认POST
- * method:'POST',
- * //可以自定义参数
- * content:'这里是提交的内容',
- * //也可以直接传json,但是只能命名为data,否则当做一般字符串处理
- * data:{
- * name:'UEditor',
- * age:'1'
- * }
- * onsuccess:function(xhr){
- * console.log(xhr.responseText);
- * },
- * onerror:function(xhr){
- * console.log(xhr.responseText);
- * }
- * })
- * @param ajaxOptions
- */
- request:function(url, ajaxOptions) {
- var ajaxRequest = creatAjaxRequest(),
- //是否超时
- timeIsOut = false,
- //默认参数
- defaultAjaxOptions = {
- method:"POST",
- timeout:5000,
- async:true,
- data:{},//需要传递对象的话只能覆盖
- onsuccess:function() {
- },
- onerror:function() {
- }
- };
- if (typeof url === "object") {
- ajaxOptions = url;
- url = ajaxOptions.url;
- }
- if (!ajaxRequest || !url) return;
- var ajaxOpts = ajaxOptions ? utils.extend(defaultAjaxOptions,ajaxOptions) : defaultAjaxOptions;
- var submitStr = json2str(ajaxOpts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing"
- //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串
- if (!utils.isEmptyObject(ajaxOpts.data)){
- submitStr += (submitStr? "&":"") + json2str(ajaxOpts.data);
- }
- //超时检测
- var timerID = setTimeout(function() {
- if (ajaxRequest.readyState != 4) {
- timeIsOut = true;
- ajaxRequest.abort();
- clearTimeout(timerID);
- }
- }, ajaxOpts.timeout);
- var method = ajaxOpts.method.toUpperCase();
- var str = url + (url.indexOf("?")==-1?"?":"&") + (method=="POST"?"":submitStr+ "&noCache=" + +new Date);
- ajaxRequest.open(method, str, ajaxOpts.async);
- ajaxRequest.onreadystatechange = function() {
- if (ajaxRequest.readyState == 4) {
- if (!timeIsOut && ajaxRequest.status == 200) {
- ajaxOpts.onsuccess(ajaxRequest);
- } else {
- ajaxOpts.onerror(ajaxRequest);
- }
- }
- };
- if (method == "POST") {
- ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- ajaxRequest.send(submitStr);
- } else {
- ajaxRequest.send(null);
- }
- }
- };
- }();
- /**
- * @file
- * @name UE.filterWord
- * @short filterWord
- * @desc 用来过滤word粘贴过来的字符串
- * @import editor.js,core/utils.js
- * @anthor zhanyi
- */
- var filterWord = UE.filterWord = function () {
- //是否是word过来的内容
- function isWordDocument( str ) {
- return /(class="?Mso|style="[^"]*\bmso\-|w:WordDocument|<v:)/ig.test( str );
- }
- //去掉小数
- function transUnit( v ) {
- v = v.replace( /[\d.]+\w+/g, function ( m ) {
- return utils.transUnitToPx(m);
- } );
- return v;
- }
- function filterPasteWord( str ) {
- return str.replace( /[\t\r\n]+/g, "" )
- .replace( /<!--[\s\S]*?-->/ig, "" )
- //转换图片
- .replace(/<v:shape [^>]*>[\s\S]*?.<\/v:shape>/gi,function(str){
- //opera能自己解析出image所这里直接返回空
- if(browser.opera){
- return '';
- }
- try{
- var width = str.match(/width:([ \d.]*p[tx])/i)[1],
- height = str.match(/height:([ \d.]*p[tx])/i)[1],
- src = str.match(/src=\s*"([^"]*)"/i)[1];
- return '<img width="'+ transUnit(width) +'" height="'+transUnit(height) +'" src="' + src + '" />';
- } catch(e){
- return '';
- }
- })
- //针对wps添加的多余标签处理
- .replace(/<\/?div[^>]*>/g,'')
- //去掉多余的属性
- .replace( /v:\w+=(["']?)[^'"]+\1/g, '' )
- .replace( /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi, "" )
- .replace( /<p [^>]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "<p><strong>$1</strong></p>" )
- //去掉多余的属性
- .replace( /\s+(class|lang|align)\s*=\s*(['"]?)[\w-]+\2/ig, "" )
- //清除多余的font/span不能匹配 有可能是空格
- .replace( /<(font|span)[^>]*>\s*<\/\1>/gi, '' )
- //处理style的问题
- .replace( /(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi, function( str, tag, tmp, style ) {
- var n = [],
- s = style.replace( /^\s+|\s+$/, '' )
- .replace(/'/g,'\'')
- .replace( /"/gi, "'" )
- .split( /;\s*/g );
- for ( var i = 0,v; v = s[i];i++ ) {
- var name, value,
- parts = v.split( ":" );
- if ( parts.length == 2 ) {
- name = parts[0].toLowerCase();
- value = parts[1].toLowerCase();
- if(/^(background)\w*/.test(name) && value.replace(/(initial|\s)/g,'').length == 0
- ||
- /^(margin)\w*/.test(name) && /^0\w+$/.test(value)
- ){
- continue;
- }
- switch ( name ) {
- case "mso-padding-alt":
- case "mso-padding-top-alt":
- case "mso-padding-right-alt":
- case "mso-padding-bottom-alt":
- case "mso-padding-left-alt":
- case "mso-margin-alt":
- case "mso-margin-top-alt":
- case "mso-margin-right-alt":
- case "mso-margin-bottom-alt":
- case "mso-margin-left-alt":
- //ie下会出现挤到一起的情况
- //case "mso-table-layout-alt":
- case "mso-height":
- case "mso-width":
- case "mso-vertical-align-alt":
- //trace:1819 ff下会解析出padding在table上
- if(!/<table/.test(tag))
- n[i] = name.replace( /^mso-|-alt$/g, "" ) + ":" + transUnit( value );
- continue;
- case "horiz-align":
- n[i] = "text-align:" + value;
- continue;
- case "vert-align":
- n[i] = "vertical-align:" + value;
- continue;
- case "font-color":
- case "mso-foreground":
- n[i] = "color:" + value;
- continue;
- case "mso-background":
- case "mso-highlight":
- n[i] = "background:" + value;
- continue;
- case "mso-default-height":
- n[i] = "min-height:" + transUnit( value );
- continue;
- case "mso-default-width":
- n[i] = "min-width:" + transUnit( value );
- continue;
- case "mso-padding-between-alt":
- n[i] = "border-collapse:separate;border-spacing:" + transUnit( value );
- continue;
- case "text-line-through":
- if ( (value == "single") || (value == "double") ) {
- n[i] = "text-decoration:line-through";
- }
- continue;
- case "mso-zero-height":
- if ( value == "yes" ) {
- n[i] = "display:none";
- }
- continue;
- case 'background':
- if(value == 'initial'){
- }
- break;
- case 'margin':
- if ( !/[1-9]/.test( value ) ) {
- continue;
- }
- }
- if ( /^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?:decor|trans)|top-bar|version|vnd|word-break)/.test( name )
- ||
- /text\-indent|padding|margin/.test(name) && /\-[\d.]+/.test(value)
- ) {
- continue;
- }
- n[i] = name + ":" + parts[1];
- }
- }
- return tag + (n.length ? ' style="' + n.join( ';').replace(/;{2,}/g,';') + '"' : '');
- })
- .replace(/[\d.]+(cm|pt)/g,function(str){
- return utils.transUnitToPx(str)
- })
- }
- return function ( html ) {
- return (isWordDocument( html ) ? filterPasteWord( html ) : html).replace( />[ \t\r\n]*</g, '><' );
- };
- }();
- ///import core
- /**
- * @description 插入内容
- * @name baidu.editor.execCommand
- * @param {String} cmdName inserthtml插入内容的命令
- * @param {String} html 要插入的内容
- * @author zhanyi
- */
- UE.commands['inserthtml'] = {
- execCommand: function (command,html,notSerialize){
- var me = this,
- range,
- div;
- if(!html){
- return;
- }
- range = me.selection.getRange();
- div = range.document.createElement( 'div' );
- div.style.display = 'inline';
- var serialize = me.serialize;
- if (!notSerialize && serialize) {
- var node = serialize.parseHTML(html);
- node = serialize.transformInput(node);
- node = serialize.filter(node);
- html = serialize.toHTML(node);
- }
- div.innerHTML = utils.trim( html );
- if ( !range.collapsed ) {
- var tmpNode = range.startContainer;
- if(domUtils.isFillChar(tmpNode)){
- range.setStartBefore(tmpNode)
- }
- tmpNode = range.endContainer;
- if(domUtils.isFillChar(tmpNode)){
- range.setEndAfter(tmpNode)
- }
- range.txtToElmBoundary();
- //结束边界可能放到了br的前边,要把br包含进来
- // x[xxx]<br/>
- if(range.endContainer && range.endContainer.nodeType == 1){
- tmpNode = range.endContainer.childNodes[range.endOffset];
- if(tmpNode && domUtils.isBr(tmpNode)){
- range.setEndAfter(tmpNode);
- }
- }
- if(range.startOffset == 0){
- tmpNode = range.startContainer;
- if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){
- tmpNode = range.endContainer;
- if(range.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){
- me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';
- range.setStart(me.body.firstChild,0).collapse(true)
- }
- }
- }
- !range.collapsed && range.deleteContents();
- if(range.startContainer.nodeType == 1){
- var child = range.startContainer.childNodes[range.startOffset],pre;
- if(child && domUtils.isBlockElm(child) && (pre = child.previousSibling) && domUtils.isBlockElm(pre)){
- range.setEnd(pre,pre.childNodes.length).collapse();
- while(child.firstChild){
- pre.appendChild(child.firstChild);
- }
- domUtils.remove(child);
- }
- }
- }
- var child,parent,pre,tmp,hadBreak = 0, nextNode;
- //如果当前位置选中了fillchar要干掉,要不会产生空行
- if(range.inFillChar()){
- child = range.startContainer;
- range.setStartBefore(child).collapse(true);
- domUtils.remove(child);
- }
- while ( child = div.firstChild ) {
- range.insertNode( child );
- nextNode = child.nextSibling;
- if ( !hadBreak && child.nodeType == domUtils.NODE_ELEMENT && domUtils.isBlockElm( child ) ){
- parent = domUtils.findParent( child,function ( node ){ return domUtils.isBlockElm( node ); } );
- if ( parent && parent.tagName.toLowerCase() != 'body' && !(dtd[parent.tagName][child.nodeName] && child.parentNode === parent)){
- if(!dtd[parent.tagName][child.nodeName]){
- pre = parent;
- }else{
- tmp = child.parentNode;
- while (tmp !== parent){
- pre = tmp;
- tmp = tmp.parentNode;
- }
- }
- domUtils.breakParent( child, pre || tmp );
- //去掉break后前一个多余的节点 <p>|<[p> ==> <p></p><div></div><p>|</p>
- var pre = child.previousSibling;
- domUtils.trimWhiteTextNode(pre);
- if(!pre.childNodes.length){
- domUtils.remove(pre);
- }
- //trace:2012,在非ie的情况,切开后剩下的节点有可能不能点入光标添加br占位
- if(!browser.ie &&
- (next = child.nextSibling) &&
- domUtils.isBlockElm(next) &&
- next.lastChild &&
- !domUtils.isBr(next.lastChild)){
- next.appendChild(me.document.createElement('br'));
- }
- hadBreak = 1;
- }
- }
- var next = child.nextSibling;
- if(!div.firstChild && next && domUtils.isBlockElm(next)){
- range.setStart(next,0).collapse(true);
- break;
- }
- range.setEndAfter( child ).collapse();
- }
- child = range.startContainer;
- if(nextNode && domUtils.isBr(nextNode)){
- domUtils.remove(nextNode)
- }
- //用chrome可能有空白展位符
- if(domUtils.isBlockElm(child) && domUtils.isEmptyNode(child)){
- if(nextNode = child.nextSibling){
- domUtils.remove(child);
- if(nextNode.nodeType == 1 && dtd.$block[nextNode.tagName]){
- range.setStart(nextNode,0).collapse(true).shrinkBoundary()
- }
- }else{
- child.innerHTML = browser.ie ? domUtils.fillChar : '<br/>';
- }
- }
- //加上true因为在删除表情等时会删两次,第一次是删的fillData
- range.select(true);
- setTimeout(function(){
- range = me.selection.getRange();
- range.scrollToView(me.autoHeightEnabled,me.autoHeightEnabled ? domUtils.getXY(me.iframe).y:0);
- me.fireEvent('afterinserthtml');
- },200);
- }
- };
- ///import core
- ///commands 自动排版
- ///commandsName autotypeset
- ///commandsTitle 自动排版
- /**
- * 自动排版
- * @function
- * @name baidu.editor.execCommands
- */
- UE.plugins['autotypeset'] = function(){
- this.setOpt({'autotypeset':{
- mergeEmptyline : true, //合并空行
- removeClass : true, //去掉冗余的class
- removeEmptyline : false, //去掉空行
- textAlign : "left", //段落的排版方式,可以是 left,right,center,justify 去掉这个属性表示不执行排版
- imageBlockLine : 'center', //图片的浮动方式,独占一行剧中,左右浮动,默认: center,left,right,none 去掉这个属性表示不执行排版
- pasteFilter : false, //根据规则过滤没事粘贴进来的内容
- clearFontSize : false, //去掉所有的内嵌字号,使用编辑器默认的字号
- clearFontFamily : false, //去掉所有的内嵌字体,使用编辑器默认的字体
- removeEmptyNode : false, // 去掉空节点
- //可以去掉的标签
- removeTagNames : utils.extend({div:1},dtd.$removeEmpty),
- indent : false, // 行首缩进
- indentValue : '2em' //行首缩进的大小
- }});
- var me = this,
- opt = me.options.autotypeset,
- remainClass = {
- 'selectTdClass':1,
- 'pagebreak':1,
- 'anchorclass':1
- },
- remainTag = {
- 'li':1
- },
- tags = {
- div:1,
- p:1,
- //trace:2183 这些也认为是行
- blockquote:1,center:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,
- span:1
- },
- highlightCont;
- //升级了版本,但配置项目里没有autotypeset
- if(!opt){
- return;
- }
- function isLine(node,notEmpty){
- if(!node || node.nodeType == 3)
- return 0;
- if(domUtils.isBr(node))
- return 1;
- if(node && node.parentNode && tags[node.tagName.toLowerCase()]){
- if(highlightCont && highlightCont.contains(node)
- ||
- node.getAttribute('pagebreak')
- ){
- return 0;
- }
- return notEmpty ? !domUtils.isEmptyBlock(node) : domUtils.isEmptyBlock(node);
- }
- }
- function removeNotAttributeSpan(node){
- if(!node.style.cssText){
- domUtils.removeAttributes(node,['style']);
- if(node.tagName.toLowerCase() == 'span' && domUtils.hasNoAttributes(node)){
- domUtils.remove(node,true);
- }
- }
- }
- function autotype(type,html){
- var me = this,cont;
- if(html){
- if(!opt.pasteFilter){
- return;
- }
- cont = me.document.createElement('div');
- cont.innerHTML = html.html;
- }else{
- cont = me.document.body;
- }
- var nodes = domUtils.getElementsByTagName(cont,'*');
- // 行首缩进,段落方向,段间距,段内间距
- for(var i=0,ci;ci=nodes[i++];){
- if(me.fireEvent('excludeNodeinautotype',ci) === true){
- continue;
- }
- //font-size
- if(opt.clearFontSize && ci.style.fontSize){
- domUtils.removeStyle(ci,'font-size');
- removeNotAttributeSpan(ci);
- }
- //font-family
- if(opt.clearFontFamily && ci.style.fontFamily){
- domUtils.removeStyle(ci,'font-family');
- removeNotAttributeSpan(ci);
- }
- if(isLine(ci)){
- //合并空行
- if(opt.mergeEmptyline ){
- var next = ci.nextSibling,tmpNode,isBr = domUtils.isBr(ci);
- while(isLine(next)){
- tmpNode = next;
- next = tmpNode.nextSibling;
- if(isBr && (!next || next && !domUtils.isBr(next))){
- break;
- }
- domUtils.remove(tmpNode);
- }
- }
- //去掉空行,保留占位的空行
- if(opt.removeEmptyline && domUtils.inDoc(ci,cont) && !remainTag[ci.parentNode.tagName.toLowerCase()] ){
- if(domUtils.isBr(ci)){
- next = ci.nextSibling;
- if(next && !domUtils.isBr(next)){
- continue;
- }
- }
- domUtils.remove(ci);
- continue;
- }
- }
- if(isLine(ci,true) && ci.tagName != 'SPAN'){
- if(opt.indent){
- ci.style.textIndent = opt.indentValue;
- }
- if(opt.textAlign){
- ci.style.textAlign = opt.textAlign;
- }
- // if(opt.lineHeight)
- // ci.style.lineHeight = opt.lineHeight + 'cm';
- }
- //去掉class,保留的class不去掉
- if(opt.removeClass && ci.className && !remainClass[ci.className.toLowerCase()]){
- if(highlightCont && highlightCont.contains(ci)){
- continue;
- }
- domUtils.removeAttributes(ci,['class']);
- }
- //表情不处理
- if(opt.imageBlockLine && ci.tagName.toLowerCase() == 'img' && !ci.getAttribute('emotion')){
- if(html){
- var img = ci;
- switch (opt.imageBlockLine){
- case 'left':
- case 'right':
- case 'none':
- var pN = img.parentNode,tmpNode,pre,next;
- while(dtd.$inline[pN.tagName] || pN.tagName == 'A'){
- pN = pN.parentNode;
- }
- tmpNode = pN;
- if(tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode,'text-align') == 'center'){
- if(!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1){
- pre = tmpNode.previousSibling;
- next = tmpNode.nextSibling;
- if(pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)){
- pre.appendChild(tmpNode.firstChild);
- while(next.firstChild){
- pre.appendChild(next.firstChild);
- }
- domUtils.remove(tmpNode);
- domUtils.remove(next);
- }else{
- domUtils.setStyle(tmpNode,'text-align','');
- }
- }
- }
- domUtils.setStyle(img,'float',opt.imageBlockLine);
- break;
- case 'center':
- if(me.queryCommandValue('imagefloat') != 'center'){
- pN = img.parentNode;
- domUtils.setStyle(img,'float','none');
- tmpNode = img;
- while(pN && domUtils.getChildCount(pN,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1
- && (dtd.$inline[pN.tagName] || pN.tagName == 'A')){
- tmpNode = pN;
- pN = pN.parentNode;
- }
- var pNode = me.document.createElement('p');
- domUtils.setAttributes(pNode,{
- style:'text-align:center'
- });
- tmpNode.parentNode.insertBefore(pNode,tmpNode);
- pNode.appendChild(tmpNode);
- domUtils.setStyle(tmpNode,'float','');
- }
- }
- }else{
- var range = me.selection.getRange();
- range.selectNode(ci).select();
- me.execCommand('imagefloat',opt.imageBlockLine);
- }
- }
- //去掉冗余的标签
- if(opt.removeEmptyNode){
- if(opt.removeTagNames[ci.tagName.toLowerCase()] && domUtils.hasNoAttributes(ci) && domUtils.isEmptyBlock(ci)){
- domUtils.remove(ci);
- }
- }
- }
- if(html){
- html.html = cont.innerHTML;
- }
- }
- if(opt.pasteFilter){
- me.addListener('beforepaste',autotype);
- }
- me.commands['autotypeset'] = {
- execCommand:function () {
- me.removeListener('beforepaste',autotype);
- if(opt.pasteFilter){
- me.addListener('beforepaste',autotype);
- }
- autotype.call(me)
- }
- };
- };
- ///import core
- ///commands 自动提交
- ///commandsName autosubmit
- ///commandsTitle 自动提交
- UE.plugins['autosubmit'] = function(){
- var me = this;
- me.commands['autosubmit'] = {
- execCommand:function () {
- var me=this,
- form = domUtils.findParentByTagName(me.iframe,"form", false);
- if (form) {
- if(me.fireEvent("beforesubmit")===false){
- return;
- }
- me.sync();
- form.submit();
- }
- }
- };
- //快捷键
- me.addshortcutkey({
- "autosubmit" : "ctrl+13" //手动提交
- });
- };
- ///import core
- ///commands 插入背景
- ///commandsName background
- ///commandsTitle 插入背景
- ///commandsDialog dialogs\background
- UE.plugins['background'] = function(){
- var me = this;
- me.addListener("getAllHtml",function(type,headHtml){
- var body = this.body,
- su = domUtils.getComputedStyle(body,"background-image"),
- url="";
- if(su.indexOf(me.options.imagePath)>0){
- url = su.substring(su.indexOf(me.options.imagePath),su.length-1).replace(/"|\(|\)/ig,"");
- }else{
- url = su!="none" ? su.replace(/url\("?|"?\)/ig,""):"";
- }
- var html = '<style type="text/css">body{';
- var bgObj = {
- "background-color" : domUtils.getComputedStyle(body,"background-color")||"#ffffff",
- 'background-image' : url ? 'url('+url+')' : '',
- 'background-repeat':domUtils.getComputedStyle(body,"background-repeat")||"",
- 'background-position': browser.ie?(domUtils.getComputedStyle(body,"background-position-x")+" "+domUtils.getComputedStyle(body,"background-position-y")):domUtils.getComputedStyle(body,"background-position"),
- 'height':domUtils.getComputedStyle(body,"height")
- };
- for ( var name in bgObj ) {
- if ( bgObj.hasOwnProperty( name ) ) {
- html += name+":"+bgObj[name]+";";
- }
- }
- html += '}</style> ';
- headHtml.push(html);
- });
- }
- ///import core
- ///import plugins\inserthtml.js
- ///commands 插入图片,操作图片的对齐方式
- ///commandsName InsertImage,ImageNone,ImageLeft,ImageRight,ImageCenter
- ///commandsTitle 图片,默认,居左,居右,居中
- ///commandsDialog dialogs\image
- /**
- * Created by .
- * User: zhanyi
- * for image
- */
- UE.commands['imagefloat'] = {
- execCommand:function (cmd, align) {
- var me = this,
- range = me.selection.getRange();
- if (!range.collapsed) {
- var img = range.getClosedNode();
- if (img && img.tagName == 'IMG') {
- switch (align) {
- case 'left':
- case 'right':
- case 'none':
- var pN = img.parentNode, tmpNode, pre, next;
- while (dtd.$inline[pN.tagName] || pN.tagName == 'A') {
- pN = pN.parentNode;
- }
- tmpNode = pN;
- if (tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode, 'text-align') == 'center') {
- if (!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode, function (node) {
- return !domUtils.isBr(node) && !domUtils.isWhitespace(node);
- }) == 1) {
- pre = tmpNode.previousSibling;
- next = tmpNode.nextSibling;
- if (pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)) {
- pre.appendChild(tmpNode.firstChild);
- while (next.firstChild) {
- pre.appendChild(next.firstChild);
- }
- domUtils.remove(tmpNode);
- domUtils.remove(next);
- } else {
- domUtils.setStyle(tmpNode, 'text-align', '');
- }
- }
- range.selectNode(img).select();
- }
- domUtils.setStyle(img, 'float', align == 'none' ? '' : align);
- if(align == 'none'){
- domUtils.removeAttributes(img,'align');
- }
- break;
- case 'center':
- if (me.queryCommandValue('imagefloat') != 'center') {
- pN = img.parentNode;
- domUtils.setStyle(img, 'float', '');
- domUtils.removeAttributes(img,'align');
- tmpNode = img;
- while (pN && domUtils.getChildCount(pN, function (node) {
- return !domUtils.isBr(node) && !domUtils.isWhitespace(node);
- }) == 1
- && (dtd.$inline[pN.tagName] || pN.tagName == 'A')) {
- tmpNode = pN;
- pN = pN.parentNode;
- }
- range.setStartBefore(tmpNode).setCursor(false);
- pN = me.document.createElement('div');
- pN.appendChild(tmpNode);
- domUtils.setStyle(tmpNode, 'float', '');
- me.execCommand('insertHtml', '<p id="_img_parent_tmp" style="text-align:center">' + pN.innerHTML + '</p>');
- tmpNode = me.document.getElementById('_img_parent_tmp');
- tmpNode.removeAttribute('id');
- tmpNode = tmpNode.firstChild;
- range.selectNode(tmpNode).select();
- //去掉后边多余的元素
- next = tmpNode.parentNode.nextSibling;
- if (next && domUtils.isEmptyNode(next)) {
- domUtils.remove(next);
- }
- }
- break;
- }
- }
- }
- },
- queryCommandValue:function () {
- var range = this.selection.getRange(),
- startNode, floatStyle;
- if (range.collapsed) {
- return 'none';
- }
- startNode = range.getClosedNode();
- if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') {
- floatStyle = startNode.getAttribute('align')||domUtils.getComputedStyle(startNode, 'float');
- if (floatStyle == 'none') {
- floatStyle = domUtils.getComputedStyle(startNode.parentNode, 'text-align') == 'center' ? 'center' : floatStyle;
- }
- return {
- left:1,
- right:1,
- center:1
- }[floatStyle] ? floatStyle : 'none';
- }
- return 'none';
- },
- queryCommandState:function () {
- var range = this.selection.getRange(),
- startNode;
- if (range.collapsed) return -1;
- startNode = range.getClosedNode();
- if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') {
- return 0;
- }
- return -1;
- }
- };
- UE.commands['insertimage'] = {
- execCommand:function (cmd, opt) {
- opt = utils.isArray(opt) ? opt : [opt];
- if (!opt.length) {
- return;
- }
- var me = this,
- range = me.selection.getRange(),
- img = range.getClosedNode();
- if (img && /img/i.test(img.tagName) && img.className != "edui-faked-video" && !img.getAttribute("word_img")) {
- var first = opt.shift();
- var floatStyle = first['floatStyle'];
- delete first['floatStyle'];
- //// img.style.border = (first.border||0) +"px solid #000";
- //// img.style.margin = (first.margin||0) +"px";
- // img.style.cssText += ';margin:' + (first.margin||0) +"px;" + 'border:' + (first.border||0) +"px solid #000";
- domUtils.setAttributes(img, first);
- me.execCommand('imagefloat', floatStyle);
- if (opt.length > 0) {
- range.setStartAfter(img).setCursor(false, true);
- me.execCommand('insertimage', opt);
- }
- } else {
- var html = [], str = '', ci;
- ci = opt[0];
- if (opt.length == 1) {
- str = '<img src="' + ci.src + '" ' + (ci.data_ue_src ? ' data_ue_src="' + ci.data_ue_src + '" ' : '') +
- (ci.width ? 'width="' + ci.width + '" ' : '') +
- (ci.height ? ' height="' + ci.height + '" ' : '') +
- (ci['floatStyle'] == 'left' || ci['floatStyle'] == 'right' ? ' style="float:' + ci['floatStyle'] + ';"' : '') +
- (ci.title && ci.title != "" ? ' title="' + ci.title + '"' : '') +
- (ci.border && ci.border != "0" ? ' border="' + ci.border + '"' : '') +
- (ci.alt && ci.alt != "" ? ' alt="' + ci.alt + '"' : '') +
- (ci.hspace && ci.hspace != "0" ? ' hspace = "' + ci.hspace + '"' : '') +
- (ci.vspace && ci.vspace != "0" ? ' vspace = "' + ci.vspace + '"' : '') + '/>';
- if (ci['floatStyle'] == 'center') {
- str = '<p style="text-align: center">' + str + '</p>';
- }
- html.push(str);
- } else {
- for (var i = 0; ci = opt[i++];) {
- str = '<p ' + (ci['floatStyle'] == 'center' ? 'style="text-align: center" ' : '') + '><img src="' + ci.src + '" ' +
- (ci.width ? 'width="' + ci.width + '" ' : '') + (ci.data_ue_src ? ' data_ue_src="' + ci.data_ue_src + '" ' : '') +
- (ci.height ? ' height="' + ci.height + '" ' : '') +
- ' style="' + (ci['floatStyle'] && ci['floatStyle'] != 'center' ? 'float:' + ci['floatStyle'] + ';' : '') +
- (ci.border || '') + '" ' +
- (ci.title ? ' title="' + ci.title + '"' : '') + ' /></p>';
- html.push(str);
- }
- }
- me.execCommand('insertHtml', html.join(''));
- }
- }
- };
- ///import core
- ///commands 段落格式,居左,居右,居中,两端对齐
- ///commandsName JustifyLeft,JustifyCenter,JustifyRight,JustifyJustify
- ///commandsTitle 居左对齐,居中对齐,居右对齐,两端对齐
- /**
- * @description 居左右中
- * @name baidu.editor.execCommand
- * @param {String} cmdName justify执行对齐方式的命令
- * @param {String} align 对齐方式:left居左,right居右,center居中,justify两端对齐
- * @author zhanyi
- */
- UE.plugins['justify']=function(){
- var me=this,
- block = domUtils.isBlockElm,
- defaultValue = {
- left:1,
- right:1,
- center:1,
- justify:1
- },
- doJustify = function (range, style) {
- var bookmark = range.createBookmark(),
- filterFn = function (node) {
- return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node);
- };
- range.enlarge(true);
- var bookmark2 = range.createBookmark(),
- current = domUtils.getNextDomNode(bookmark2.start, false, filterFn),
- tmpRange = range.cloneRange(),
- tmpNode;
- while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) {
- if (current.nodeType == 3 || !block(current)) {
- tmpRange.setStartBefore(current);
- while (current && current !== bookmark2.end && !block(current)) {
- tmpNode = current;
- current = domUtils.getNextDomNode(current, false, null, function (node) {
- return !block(node);
- });
- }
- tmpRange.setEndAfter(tmpNode);
- var common = tmpRange.getCommonAncestor();
- if (!domUtils.isBody(common) && block(common)) {
- domUtils.setStyles(common, utils.isString(style) ? {'text-align':style} : style);
- current = common;
- } else {
- var p = range.document.createElement('p');
- domUtils.setStyles(p, utils.isString(style) ? {'text-align':style} : style);
- var frag = tmpRange.extractContents();
- p.appendChild(frag);
- tmpRange.insertNode(p);
- current = p;
- }
- current = domUtils.getNextDomNode(current, false, filterFn);
- } else {
- current = domUtils.getNextDomNode(current, true, filterFn);
- }
- }
- return range.moveToBookmark(bookmark2).moveToBookmark(bookmark);
- };
- UE.commands['justify'] = {
- execCommand:function (cmdName, align) {
- var range = this.selection.getRange(),
- txt;
- //闭合时单独处理
- if (range.collapsed) {
- txt = this.document.createTextNode('p');
- range.insertNode(txt);
- }
- doJustify(range, align);
- if (txt) {
- range.setStartBefore(txt).collapse(true);
- domUtils.remove(txt);
- }
- range.select();
- return true;
- },
- queryCommandValue:function () {
- var startNode = this.selection.getStart(),
- value = domUtils.getComputedStyle(startNode, 'text-align');
- return defaultValue[value] ? value : 'left';
- },
- queryCommandState:function () {
- var start = this.selection.getStart(),
- cell = start && domUtils.findParentByTagName(start, ["td", "th","caption"], true);
- return cell? -1:0;
- }
- };
- };
- ///import core
- ///import plugins\removeformat.js
- ///commands 字体颜色,背景色,字号,字体,下划线,删除线
- ///commandsName ForeColor,BackColor,FontSize,FontFamily,Underline,StrikeThrough
- ///commandsTitle 字体颜色,背景色,字号,字体,下划线,删除线
- /**
- * @description 字体
- * @name baidu.editor.execCommand
- * @param {String} cmdName 执行的功能名称
- * @param {String} value 传入的值
- */
- UE.plugins['font'] = function() {
- var me = this,
- fonts = {
- 'forecolor':'color',
- 'backcolor':'background-color',
- 'fontsize':'font-size',
- 'fontfamily':'font-family',
- 'underline':'text-decoration',
- 'strikethrough':'text-decoration'
- };
- me.setOpt({
- 'fontfamily':[
- { name:'songti',val:'宋体,SimSun'},
- { name:'yahei',val:'微软雅黑,Microsoft YaHei'},
- { name:'kaiti',val:'楷体,楷体_GB2312, SimKai'},
- { name:'heiti',val:'黑体, SimHei'},
- { name:'lishu',val:'隶书, SimLi'},
- { name:'andaleMono',val:'andale mono'},
- { name:'arial',val:'arial, helvetica,sans-serif'},
- { name:'arialBlack',val:'arial black,avant garde'},
- { name:'comicSansMs',val:'comic sans ms'},
- { name:'impact',val:'impact,chicago'},
- { name:'timesNewRoman',val:'times new roman'}
- ],
- 'fontsize':[10, 11, 12, 14, 16, 18, 20, 24, 36]
- });
- for ( var p in fonts ) {
- (function( cmd, style ) {
- UE.commands[cmd] = {
- execCommand : function( cmdName, value ) {
- value = value || (this.queryCommandState(cmdName) ? 'none' : cmdName == 'underline' ? 'underline' : 'line-through');
- var me = this,
- range = this.selection.getRange(),
- text;
- if ( value == 'default' ) {
- if(range.collapsed){
- text = me.document.createTextNode('font');
- range.insertNode(text).select();
- }
- me.execCommand( 'removeFormat', 'span,a', style);
- if(text){
- range.setStartBefore(text).setCursor();
- domUtils.remove(text);
- }
- } else {
- if ( !range.collapsed ) {
- if((cmd == 'underline'||cmd=='strikethrough') && me.queryCommandValue(cmd)){
- me.execCommand( 'removeFormat', 'span,a', style );
- }
- range = me.selection.getRange();
- range.applyInlineStyle( 'span', {'style':style + ':' + value} ).select();
- } else {
- var span = domUtils.findParentByTagName(range.startContainer,'span',true);
- text = me.document.createTextNode('font');
- if(span && !span.children.length && !span[browser.ie ? 'innerText':'textContent'].replace(fillCharReg,'').length){
- //for ie hack when enter
- range.insertNode(text);
- if(cmd == 'underline'||cmd=='strikethrough'){
- range.selectNode(text).select();
- me.execCommand( 'removeFormat','span,a', style, null );
- span = domUtils.findParentByTagName(text,'span',true);
- range.setStartBefore(text);
- }
- span.style.cssText += ';' + style + ':' + value;
- range.collapse(true).select();
- }else{
- range.insertNode(text);
- range.selectNode(text).select();
- span = range.document.createElement( 'span' );
- if(cmd == 'underline'||cmd=='strikethrough'){
- //a标签内的不处理跳过
- if(domUtils.findParentByTagName(text,'a',true)){
- range.setStartBefore(text).setCursor();
- domUtils.remove(text);
- return;
- }
- me.execCommand( 'removeFormat','span,a', style );
- }
- span.style.cssText = style + ':' + value;
- text.parentNode.insertBefore(span,text);
- //修复,span套span 但样式不继承的问题
- if(!browser.ie || browser.ie && browser.version == 9){
- var spanParent = span.parentNode;
- while(!domUtils.isBlockElm(spanParent)){
- if(spanParent.tagName == 'SPAN'){
- //opera合并style不会加入";"
- span.style.cssText = spanParent.style.cssText + ";" + span.style.cssText;
- }
- spanParent = spanParent.parentNode;
- }
- }
- if(opera){
- setTimeout(function(){
- range.setStart(span,0).setCursor();
- });
- }else{
- range.setStart(span,0).setCursor();
- }
- //trace:981
- //domUtils.mergeToParent(span)
- }
- domUtils.remove(text);
- }
- }
- return true;
- },
- queryCommandValue : function (cmdName) {
- var startNode = this.selection.getStart();
- //trace:946
- if(cmdName == 'underline'||cmdName=='strikethrough' ){
- var tmpNode = startNode,value;
- while(tmpNode && !domUtils.isBlockElm(tmpNode) && !domUtils.isBody(tmpNode)){
- if(tmpNode.nodeType == 1){
- value = domUtils.getComputedStyle( tmpNode, style );
- if(value != 'none'){
- return value;
- }
- }
- tmpNode = tmpNode.parentNode;
- }
- return 'none';
- }
- return domUtils.getComputedStyle( startNode, style );
- },
- queryCommandState : function(cmdName){
- if(!(cmdName == 'underline'||cmdName=='strikethrough')){
- return 0;
- }
- return this.queryCommandValue(cmdName) == (cmdName == 'underline' ? 'underline' : 'line-through');
- }
- };
- })( p, fonts[p] );
- }
- };
- ///import core
- ///commands 超链接,取消链接
- ///commandsName Link,Unlink
- ///commandsTitle 超链接,取消链接
- ///commandsDialog dialogs\link
- /**
- * 超链接
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName link插入超链接
- * @param {Object} options url地址,title标题,target是否打开新页
- * @author zhanyi
- */
- /**
- * 取消链接
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName unlink取消链接
- * @author zhanyi
- */
- (function() {
- function optimize( range ) {
- var start = range.startContainer,end = range.endContainer;
- if ( start = domUtils.findParentByTagName( start, 'a', true ) ) {
- range.setStartBefore( start );
- }
- if ( end = domUtils.findParentByTagName( end, 'a', true ) ) {
- range.setEndAfter( end );
- }
- }
- UE.commands['unlink'] = {
- execCommand : function() {
- var range = this.selection.getRange(),
- bookmark;
- if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){
- return;
- }
- bookmark = range.createBookmark();
- optimize( range );
- range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select();
- },
- queryCommandState : function(){
- return !this.highlight && this.queryCommandValue('link') ? 0 : -1;
- }
- };
- function doLink(range,opt,me){
- var rngClone = range.cloneRange(),
- link = me.queryCommandValue('link');
- optimize( range = range.adjustmentBoundary() );
- var start = range.startContainer;
- if(start.nodeType == 1 && link){
- start = start.childNodes[range.startOffset];
- if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\s*:\s*\/\//.test(start[browser.ie?'innerText':'textContent'])){
- start[browser.ie ? 'innerText' : 'textContent'] = utils.html(opt.textValue||opt.href);
- }
- }
- if( !rngClone.collapsed || link){
- range.removeInlineStyle( 'a' );
- rngClone = range.cloneRange();
- }
- if ( rngClone.collapsed ) {
- var a = range.document.createElement( 'a'),
- text = '';
- if(opt.textValue){
- text = utils.html(opt.textValue);
- delete opt.textValue;
- }else{
- text = utils.html(opt.href);
- }
- domUtils.setAttributes( a, opt );
- start = domUtils.findParentByTagName( rngClone.startContainer, 'a', true );
- if(start && domUtils.isInNodeEndBoundary(rngClone,start)){
- range.setStartAfter(start).collapse(true);
- }
- a[browser.ie ? 'innerText' : 'textContent'] = text;
- range.insertNode(a).selectNode( a );
- } else {
- range.applyInlineStyle( 'a', opt );
- }
- }
- UE.commands['link'] = {
- execCommand : function( cmdName, opt ) {
- var range;
- opt.data_ue_src && (opt.data_ue_src = utils.unhtml(opt.data_ue_src,/[<">]/g));
- opt.href && (opt.href = utils.unhtml(opt.href,/[<">]/g));
- opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<">]/g));
- doLink(range=this.selection.getRange(),opt,this);
- //闭合都不加占位符,如果加了会在a后边多个占位符节点,导致a是图片背景组成的列表,出现空白问题
- range.collapse().select(true);
- },
- queryCommandValue : function() {
- var range = this.selection.getRange(),
- node;
- if ( range.collapsed ) {
- // node = this.selection.getStart();
- //在ie下getstart()取值偏上了
- node = range.startContainer;
- node = node.nodeType == 1 ? node : node.parentNode;
- if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) {
- return node;
- }
- } else {
- //trace:1111 如果是<p><a>xx</a></p> startContainer是p就会找不到a
- range.shrinkBoundary();
- var start = range.startContainer.nodeType == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset],
- end = range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1],
- common = range.getCommonAncestor();
- node = domUtils.findParentByTagName( common, 'a', true );
- if ( !node && common.nodeType == 1){
- var as = common.getElementsByTagName( 'a' ),
- ps,pe;
- for ( var i = 0,ci; ci = as[i++]; ) {
- ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end);
- if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)
- &&
- (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)
- ) {
- node = ci;
- break;
- }
- }
- }
- return node;
- }
- },
- queryCommandState : function() {
- //判断如果是视频的话连接不可用
- //fix 853
- var img = this.selection.getRange().getClosedNode(),
- flag = img && (img.className == "edui-faked-video");
- return flag ? -1 : 0;
- }
- };
- })();
- ///import core
- ///import plugins\inserthtml.js
- ///commands 插入框架
- ///commandsName InsertFrame
- ///commandsTitle 插入Iframe
- ///commandsDialog dialogs\insertframe
- UE.plugins['insertframe'] = function() {
- var me =this;
- function deleteIframe(){
- me._iframe && delete me._iframe;
- }
- me.addListener("selectionchange",function(){
- deleteIframe();
- });
- };
- ///import core
- ///commands 涂鸦
- ///commandsName Scrawl
- ///commandsTitle 涂鸦
- ///commandsDialog dialogs\scrawl
- UE.commands['scrawl'] = {
- queryCommandState : function(){
- return ( browser.ie && browser.version <= 8 ) ? -1 :0;
- }
- };
- ///import core
- ///commands 清除格式
- ///commandsName RemoveFormat
- ///commandsTitle 清除格式
- /**
- * @description 清除格式
- * @name baidu.editor.execCommand
- * @param {String} cmdName removeformat清除格式命令
- * @param {String} tags 以逗号隔开的标签。如:span,a
- * @param {String} style 样式
- * @param {String} attrs 属性
- * @param {String} notIncluedA 是否把a标签切开
- * @author zhanyi
- */
- UE.plugins['removeformat'] = function(){
- var me = this;
- me.setOpt({
- 'removeFormatTags': 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var',
- 'removeFormatAttributes':'class,style,lang,width,height,align,hspace,valign'
- });
- me.commands['removeformat'] = {
- execCommand : function( cmdName, tags, style, attrs,notIncludeA ) {
- var tagReg = new RegExp( '^(?:' + (tags || this.options.removeFormatTags).replace( /,/g, '|' ) + ')$', 'i' ) ,
- removeFormatAttributes = style ? [] : (attrs || this.options.removeFormatAttributes).split( ',' ),
- range = new dom.Range( this.document ),
- bookmark,node,parent,
- filter = function( node ) {
- return node.nodeType == 1;
- };
- function isRedundantSpan (node) {
- if (node.nodeType == 3 || node.tagName.toLowerCase() != 'span'){
- return 0;
- }
- if (browser.ie) {
- //ie 下判断实效,所以只能简单用style来判断
- //return node.style.cssText == '' ? 1 : 0;
- var attrs = node.attributes;
- if ( attrs.length ) {
- for ( var i = 0,l = attrs.length; i<l; i++ ) {
- if ( attrs[i].specified ) {
- return 0;
- }
- }
- return 1;
- }
- }
- return !node.attributes.length;
- }
- function doRemove( range ) {
- var bookmark1 = range.createBookmark();
- if ( range.collapsed ) {
- range.enlarge( true );
- }
- //不能把a标签切了
- if(!notIncludeA){
- var aNode = domUtils.findParentByTagName(range.startContainer,'a',true);
- if(aNode){
- range.setStartBefore(aNode);
- }
- aNode = domUtils.findParentByTagName(range.endContainer,'a',true);
- if(aNode){
- range.setEndAfter(aNode);
- }
- }
- bookmark = range.createBookmark();
- node = bookmark.start;
- //切开始
- while ( (parent = node.parentNode) && !domUtils.isBlockElm( parent ) ) {
- domUtils.breakParent( node, parent );
- domUtils.clearEmptySibling( node );
- }
- if ( bookmark.end ) {
- //切结束
- node = bookmark.end;
- while ( (parent = node.parentNode) && !domUtils.isBlockElm( parent ) ) {
- domUtils.breakParent( node, parent );
- domUtils.clearEmptySibling( node );
- }
- //开始去除样式
- var current = domUtils.getNextDomNode( bookmark.start, false, filter ),
- next;
- while ( current ) {
- if ( current == bookmark.end ) {
- break;
- }
- next = domUtils.getNextDomNode( current, true, filter );
- if ( !dtd.$empty[current.tagName.toLowerCase()] && !domUtils.isBookmarkNode( current ) ) {
- if ( tagReg.test( current.tagName ) ) {
- if ( style ) {
- domUtils.removeStyle( current, style );
- if ( isRedundantSpan( current ) && style != 'text-decoration'){
- domUtils.remove( current, true );
- }
- } else {
- domUtils.remove( current, true );
- }
- } else {
- //trace:939 不能把list上的样式去掉
- if(!dtd.$tableContent[current.tagName] && !dtd.$list[current.tagName]){
- domUtils.removeAttributes( current, removeFormatAttributes );
- if ( isRedundantSpan( current ) ){
- domUtils.remove( current, true );
- }
- }
- }
- }
- current = next;
- }
- }
- //trace:1035
- //trace:1096 不能把td上的样式去掉,比如边框
- var pN = bookmark.start.parentNode;
- if(domUtils.isBlockElm(pN) && !dtd.$tableContent[pN.tagName] && !dtd.$list[pN.tagName]){
- domUtils.removeAttributes( pN,removeFormatAttributes );
- }
- pN = bookmark.end.parentNode;
- if(bookmark.end && domUtils.isBlockElm(pN) && !dtd.$tableContent[pN.tagName]&& !dtd.$list[pN.tagName]){
- domUtils.removeAttributes( pN,removeFormatAttributes );
- }
- range.moveToBookmark( bookmark ).moveToBookmark(bookmark1);
- //清除冗余的代码 <b><bookmark></b>
- var node = range.startContainer,
- tmp,
- collapsed = range.collapsed;
- while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){
- tmp = node.parentNode;
- range.setStartBefore(node);
- //trace:937
- //更新结束边界
- if(range.startContainer === range.endContainer){
- range.endOffset--;
- }
- domUtils.remove(node);
- node = tmp;
- }
- if(!collapsed){
- node = range.endContainer;
- while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){
- tmp = node.parentNode;
- range.setEndBefore(node);
- domUtils.remove(node);
- node = tmp;
- }
- }
- }
- range = this.selection.getRange();
- doRemove( range );
- range.select();
- }
- };
- };
- ///import core
- ///commands 引用
- ///commandsName BlockQuote
- ///commandsTitle 引用
- /**
- *
- * 引用模块实现
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName blockquote引用
- */
- UE.plugins['blockquote'] = function(){
- var me = this;
- function getObj(editor){
- return domUtils.filterNodeList(editor.selection.getStartElementPath(),'blockquote');
- };
- me.commands['blockquote'] = {
- execCommand : function( cmdName, attrs ) {
- var range = this.selection.getRange(),
- obj = getObj(this),
- blockquote = dtd.blockquote,
- bookmark = range.createBookmark();
- if ( obj ) {
- var start = range.startContainer,
- startBlock = domUtils.isBlockElm(start) ? start : domUtils.findParent(start,function(node){return domUtils.isBlockElm(node)}),
- end = range.endContainer,
- endBlock = domUtils.isBlockElm(end) ? end : domUtils.findParent(end,function(node){return domUtils.isBlockElm(node)});
- //处理一下li
- startBlock = domUtils.findParentByTagName(startBlock,'li',true) || startBlock;
- endBlock = domUtils.findParentByTagName(endBlock,'li',true) || endBlock;
- if(startBlock.tagName == 'LI' || startBlock.tagName == 'TD' || startBlock === obj){
- domUtils.remove(obj,true);
- }else{
- domUtils.breakParent(startBlock,obj);
- }
- if(startBlock !== endBlock){
- obj = domUtils.findParentByTagName(endBlock,'blockquote');
- if(obj){
- if(endBlock.tagName == 'LI' || endBlock.tagName == 'TD'){
- domUtils.remove(obj,true);
- }else{
- domUtils.breakParent(endBlock,obj);
- }
- }
- }
- var blockquotes = domUtils.getElementsByTagName(this.document,'blockquote');
- for(var i=0,bi;bi=blockquotes[i++];){
- if(!bi.childNodes.length){
- domUtils.remove(bi);
- }else if(domUtils.getPosition(bi,startBlock)&domUtils.POSITION_FOLLOWING && domUtils.getPosition(bi,endBlock)&domUtils.POSITION_PRECEDING){
- domUtils.remove(bi,true);
- }
- }
- } else {
- var tmpRange = range.cloneRange(),
- node = tmpRange.startContainer.nodeType == 1 ? tmpRange.startContainer : tmpRange.startContainer.parentNode,
- preNode = node,
- doEnd = 1;
- //调整开始
- while ( 1 ) {
- if ( domUtils.isBody(node) ) {
- if ( preNode !== node ) {
- if ( range.collapsed ) {
- tmpRange.selectNode( preNode );
- doEnd = 0;
- } else {
- tmpRange.setStartBefore( preNode );
- }
- }else{
- tmpRange.setStart(node,0);
- }
- break;
- }
- if ( !blockquote[node.tagName] ) {
- if ( range.collapsed ) {
- tmpRange.selectNode( preNode );
- } else{
- tmpRange.setStartBefore( preNode);
- }
- break;
- }
- preNode = node;
- node = node.parentNode;
- }
- //调整结束
- if ( doEnd ) {
- preNode = node = node = tmpRange.endContainer.nodeType == 1 ? tmpRange.endContainer : tmpRange.endContainer.parentNode;
- while ( 1 ) {
- if ( domUtils.isBody( node ) ) {
- if ( preNode !== node ) {
- tmpRange.setEndAfter( preNode );
- } else {
- tmpRange.setEnd( node, node.childNodes.length );
- }
- break;
- }
- if ( !blockquote[node.tagName] ) {
- tmpRange.setEndAfter( preNode );
- break;
- }
- preNode = node;
- node = node.parentNode;
- }
- }
- node = range.document.createElement( 'blockquote' );
- domUtils.setAttributes( node, attrs );
- node.appendChild( tmpRange.extractContents() );
- tmpRange.insertNode( node );
- //去除重复的
- var childs = domUtils.getElementsByTagName(node,'blockquote');
- for(var i=0,ci;ci=childs[i++];){
- if(ci.parentNode){
- domUtils.remove(ci,true);
- }
- }
- }
- range.moveToBookmark( bookmark ).select();
- },
- queryCommandState : function() {
- return getObj(this) ? 1 : 0;
- }
- };
- };
- ///import core
- ///commands 大小写转换
- ///commandsName touppercase,tolowercase
- ///commandsTitle 大写,小写
- /**
- * 大小写转换
- * @function
- * @name baidu.editor.execCommands
- * @param {String} cmdName cmdName="convertcase"
- */
- UE.commands['touppercase'] =
- UE.commands['tolowercase'] = {
- execCommand:function (cmd) {
- var me = this;
- var rng = me.selection.getRange();
- if(rng.collapsed){
- return rng;
- }
- var bk = rng.createBookmark(),
- bkEnd = bk.end,
- filterFn = function( node ) {
- return !domUtils.isBr(node) && !domUtils.isWhitespace( node );
- },
- curNode = domUtils.getNextDomNode( bk.start, false, filterFn );
- while ( curNode && (domUtils.getPosition( curNode, bkEnd ) & domUtils.POSITION_PRECEDING) ) {
- if ( curNode.nodeType == 3 ) {
- curNode.nodeValue = curNode.nodeValue[cmd == 'touppercase' ? 'toUpperCase' : 'toLowerCase']();
- }
- curNode = domUtils.getNextDomNode( curNode, true, filterFn );
- if(curNode === bkEnd){
- break;
- }
- }
- rng.moveToBookmark(bk).select();
- }
- };
- ///import core
- ///import plugins\paragraph.js
- ///commands 首行缩进
- ///commandsName Outdent,Indent
- ///commandsTitle 取消缩进,首行缩进
- /**
- * 首行缩进
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName outdent取消缩进,indent缩进
- */
- UE.commands['indent'] = {
- execCommand : function() {
- var me = this,value = me.queryCommandState("indent") ? "0em" : (me.options.indentValue || '2em');
- me.execCommand('Paragraph','p',{style:'text-indent:'+ value});
- },
- queryCommandState : function() {
- var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6');
- return pN && pN.style.textIndent && parseInt(pN.style.textIndent) ? 1 : 0;
- }
- };
- ///import core
- ///commands 打印
- ///commandsName Print
- ///commandsTitle 打印
- /**
- * @description 打印
- * @name baidu.editor.execCommand
- * @param {String} cmdName print打印编辑器内容
- * @author zhanyi
- */
- UE.commands['print'] = {
- execCommand : function(){
- this.window.print();
- },
- notNeedUndo : 1
- };
- ///import core
- ///commands 预览
- ///commandsName Preview
- ///commandsTitle 预览
- /**
- * 预览
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName preview预览编辑器内容
- */
- UE.commands['preview'] = {
- execCommand : function(){
- var w = window.open('', '_blank', ''),
- d = w.document;
- d.open();
- d.write('<html><head><script src="'+this.options.UEDITOR_HOME_URL+'uparse.js"></script><script>' +
- "setTimeout(function(){uParse('div',{" +
- " 'highlightJsUrl':'"+this.options.UEDITOR_HOME_URL+"third-party/SyntaxHighlighter/shCore.js'," +
- " 'highlightCssUrl':'"+this.options.UEDITOR_HOME_URL+"third-party/SyntaxHighlighter/shCoreDefault.css'" +
- "})},300)" +
- '</script></head><body><div>'+this.getContent(null,null,true)+'</div></body></html>');
- d.close();
- },
- notNeedUndo : 1
- };
- ///import core
- ///commands 全选
- ///commandsName SelectAll
- ///commandsTitle 全选
- /**
- * 选中所有
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName selectall选中编辑器里的所有内容
- * @author zhanyi
- */
- UE.plugins['selectall'] = function(){
- var me = this;
- me.commands['selectall'] = {
- execCommand : function(){
- //去掉了原生的selectAll,因为会出现报错和当内容为空时,不能出现闭合状态的光标
- var me = this,body = me.body,
- range = me.selection.getRange();
- range.selectNodeContents(body);
- if(domUtils.isEmptyBlock(body)){
- //opera不能自动合并到元素的里边,要手动处理一下
- if(browser.opera && body.firstChild && body.firstChild.nodeType == 1){
- range.setStartAtFirst(body.firstChild);
- }
- range.collapse(true);
- }
- range.select(true);
- },
- notNeedUndo : 1
- };
- function isBoundaryNode(node,dir){
- var tmp;
- while(!domUtils.isBody(node)){
- tmp = node;
- node = node.parentNode;
- if(tmp !== node[dir]){
- return false;
- }
- }
- return true;
- }
- me.addListener('keydown', function(type, evt) {
- var rng = me.selection.getRange();
- if(!rng.collapsed && !(evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey)){
- var tmpNode = rng.startContainer;
- if(domUtils.isFillChar(tmpNode)){
- rng.setStartBefore(tmpNode)
- }
- tmpNode = rng.endContainer;
- if(domUtils.isFillChar(tmpNode)){
- rng.setEndAfter(tmpNode)
- }
- rng.txtToElmBoundary();
- if(rng.startOffset == 0){
- tmpNode = rng.startContainer;
- if(isBoundaryNode(tmpNode,'firstChild')){
- tmpNode = rng.endContainer;
- if(rng.endOffset == rng.endContainer.childNodes.length && isBoundaryNode(tmpNode,'lastChild') ){
- me.fireEvent('saveScene');
- me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';
- rng.setStart(me.body.firstChild,0).setCursor(false,true);
- me.fireEvent('saveScene');
- browser.ie && me._selectionChange();
- return;
- }
- }
- }
- }
- });
- //快捷键
- me.addshortcutkey({
- "selectAll" : "ctrl+65"
- });
- };
- ///import core
- ///commands 格式
- ///commandsName Paragraph
- ///commandsTitle 段落格式
- /**
- * 段落样式
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName paragraph插入段落执行命令
- * @param {String} style 标签值为:'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
- * @param {String} attrs 标签的属性
- * @author zhanyi
- */
- UE.plugins['paragraph'] = function() {
- var me = this,
- block = domUtils.isBlockElm,
- notExchange = ['TD','LI','PRE'],
- doParagraph = function(range,style,attrs,sourceCmdName){
- var bookmark = range.createBookmark(),
- filterFn = function( node ) {
- return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace( node );
- },
- para;
- range.enlarge( true );
- var bookmark2 = range.createBookmark(),
- current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ),
- tmpRange = range.cloneRange(),
- tmpNode;
- while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) {
- if ( current.nodeType == 3 || !block( current ) ) {
- tmpRange.setStartBefore( current );
- while ( current && current !== bookmark2.end && !block( current ) ) {
- tmpNode = current;
- current = domUtils.getNextDomNode( current, false, null, function( node ) {
- return !block( node );
- } );
- }
- tmpRange.setEndAfter( tmpNode );
-
- para = range.document.createElement( style );
- if(attrs){
- domUtils.setAttributes(para,attrs);
- if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){
- para.style.cssText = attrs.style;
- }
- }
- para.appendChild( tmpRange.extractContents() );
- //需要内容占位
- if(domUtils.isEmptyNode(para)){
- domUtils.fillChar(range.document,para);
-
- }
- tmpRange.insertNode( para );
- var parent = para.parentNode;
- //如果para上一级是一个block元素且不是body,td就删除它
- if ( block( parent ) && !domUtils.isBody( para.parentNode ) && utils.indexOf(notExchange,parent.tagName)==-1) {
- //存储dir,style
- if(!(sourceCmdName && sourceCmdName == 'customstyle')){
- parent.getAttribute('dir') && para.setAttribute('dir',parent.getAttribute('dir'));
- //trace:1070
- parent.style.cssText && (para.style.cssText = parent.style.cssText + ';' + para.style.cssText);
- //trace:1030
- parent.style.textAlign && !para.style.textAlign && (para.style.textAlign = parent.style.textAlign);
- parent.style.textIndent && !para.style.textIndent && (para.style.textIndent = parent.style.textIndent);
- parent.style.padding && !para.style.padding && (para.style.padding = parent.style.padding);
- }
- //trace:1706 选择的就是h1-6要删除
- if(attrs && /h\d/i.test(parent.tagName) && !/h\d/i.test(para.tagName) ){
- domUtils.setAttributes(parent,attrs);
- if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){
- parent.style.cssText = attrs.style;
- }
- domUtils.remove(para,true);
- para = parent;
- }else{
- domUtils.remove( para.parentNode, true );
- }
- }
- if( utils.indexOf(notExchange,parent.tagName)!=-1){
- current = parent;
- }else{
- current = para;
- }
- current = domUtils.getNextDomNode( current, false, filterFn );
- } else {
- current = domUtils.getNextDomNode( current, true, filterFn );
- }
- }
- return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark );
- };
- me.setOpt('paragraph',{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''});
- me.commands['paragraph'] = {
- execCommand : function( cmdName, style,attrs,sourceCmdName ) {
- var range = this.selection.getRange();
- //闭合时单独处理
- if(range.collapsed){
- var txt = this.document.createTextNode('p');
- range.insertNode(txt);
- //去掉冗余的fillchar
- if(browser.ie){
- var node = txt.previousSibling;
- if(node && domUtils.isWhitespace(node)){
- domUtils.remove(node);
- }
- node = txt.nextSibling;
- if(node && domUtils.isWhitespace(node)){
- domUtils.remove(node);
- }
- }
- }
- range = doParagraph(range,style,attrs,sourceCmdName);
- if(txt){
- range.setStartBefore(txt).collapse(true);
- pN = txt.parentNode;
- domUtils.remove(txt);
- if(domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)){
- domUtils.fillNode(this.document,pN);
- }
- }
- if(browser.gecko && range.collapsed && range.startContainer.nodeType == 1){
- var child = range.startContainer.childNodes[range.startOffset];
- if(child && child.nodeType == 1 && child.tagName.toLowerCase() == style){
- range.setStart(child,0).collapse(true);
- }
- }
- //trace:1097 原来有true,原因忘了,但去了就不能清除多余的占位符了
- range.select();
- return true;
- },
- queryCommandValue : function() {
- var node = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6');
- return node ? node.tagName.toLowerCase() : '';
- }
- };
- };
- ///import core
- ///commands 输入的方向
- ///commandsName DirectionalityLtr,DirectionalityRtl
- ///commandsTitle 从左向右输入,从右向左输入
- /**
- * 输入的方向
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName directionality执行函数的参数
- * @param {String} forward ltr从左向右输入,rtl从右向左输入
- */
- (function() {
- var block = domUtils.isBlockElm ,
- getObj = function(editor){
- // var startNode = editor.selection.getStart(),
- // parents;
- // if ( startNode ) {
- // //查找所有的是block的父亲节点
- // parents = domUtils.findParents( startNode, true, block, true );
- // for ( var i = 0,ci; ci = parents[i++]; ) {
- // if ( ci.getAttribute( 'dir' ) ) {
- // return ci;
- // }
- // }
- // }
- return domUtils.filterNodeList(editor.selection.getStartElementPath(),function(n){return n.getAttribute('dir')});
- },
- doDirectionality = function(range,editor,forward){
-
- var bookmark,
- filterFn = function( node ) {
- return node.nodeType == 1 ? !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node);
- },
- obj = getObj( editor );
- if ( obj && range.collapsed ) {
- obj.setAttribute( 'dir', forward );
- return range;
- }
- bookmark = range.createBookmark();
- range.enlarge( true );
- var bookmark2 = range.createBookmark(),
- current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ),
- tmpRange = range.cloneRange(),
- tmpNode;
- while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) {
- if ( current.nodeType == 3 || !block( current ) ) {
- tmpRange.setStartBefore( current );
- while ( current && current !== bookmark2.end && !block( current ) ) {
- tmpNode = current;
- current = domUtils.getNextDomNode( current, false, null, function( node ) {
- return !block( node );
- } );
- }
- tmpRange.setEndAfter( tmpNode );
- var common = tmpRange.getCommonAncestor();
- if ( !domUtils.isBody( common ) && block( common ) ) {
- //遍历到了block节点
- common.setAttribute( 'dir', forward );
- current = common;
- } else {
- //没有遍历到,添加一个block节点
- var p = range.document.createElement( 'p' );
- p.setAttribute( 'dir', forward );
- var frag = tmpRange.extractContents();
- p.appendChild( frag );
- tmpRange.insertNode( p );
- current = p;
- }
- current = domUtils.getNextDomNode( current, false, filterFn );
- } else {
- current = domUtils.getNextDomNode( current, true, filterFn );
- }
- }
- return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark );
- };
- UE.commands['directionality'] = {
- execCommand : function( cmdName,forward ) {
- var range = this.selection.getRange();
- //闭合时单独处理
- if(range.collapsed){
- var txt = this.document.createTextNode('d');
- range.insertNode(txt);
- }
- doDirectionality(range,this,forward);
- if(txt){
- range.setStartBefore(txt).collapse(true);
- domUtils.remove(txt);
- }
- range.select();
- return true;
- },
- queryCommandValue : function() {
- var node = getObj(this);
- return node ? node.getAttribute('dir') : 'ltr';
- }
- };
- })();
- ///import core
- ///import plugins\inserthtml.js
- ///commands 分割线
- ///commandsName Horizontal
- ///commandsTitle 分隔线
- /**
- * 分割线
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName horizontal插入分割线
- */
- UE.commands['horizontal'] = {
- execCommand : function( cmdName ) {
- var me = this;
- if(me.queryCommandState(cmdName)!==-1){
- me.execCommand('insertHtml','<hr>');
- var range = me.selection.getRange(),
- start = range.startContainer;
- if(start.nodeType == 1 && !start.childNodes[range.startOffset] ){
- var tmp;
- if(tmp = start.childNodes[range.startOffset - 1]){
- if(tmp.nodeType == 1 && tmp.tagName == 'HR'){
- if(me.options.enterTag == 'p'){
- tmp = me.document.createElement('p');
- range.insertNode(tmp);
- range.setStart(tmp,0).setCursor();
- }else{
- tmp = me.document.createElement('br');
- range.insertNode(tmp);
- range.setStartBefore(tmp).setCursor();
- }
- }
- }
- }
- return true;
- }
- },
- //边界在table里不能加分隔线
- queryCommandState : function() {
- return domUtils.filterNodeList(this.selection.getStartElementPath(),'table') ? -1 : 0;
- }
- };
- ///import core
- ///import plugins\inserthtml.js
- ///commands 日期,时间
- ///commandsName Date,Time
- ///commandsTitle 日期,时间
- /**
- * 插入日期
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName date插入日期
- * @author zhuwenxuan
- */
- /**
- * 插入时间
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName time插入时间
- * @author zhuwenxuan
- */
- UE.commands['time'] = UE.commands["date"] = {
- execCommand : function(cmd){
- var date = new Date;
- this.execCommand('insertHtml',cmd == "time" ?
- (date.getHours()+":"+ (date.getMinutes()<10 ? "0"+date.getMinutes() : date.getMinutes())+":"+(date.getSeconds()<10 ? "0"+date.getSeconds() : date.getSeconds())) :
- (date.getFullYear()+"-"+((date.getMonth()+1)<10 ? "0"+(date.getMonth()+1) : date.getMonth()+1)+"-"+(date.getDate()<10?"0"+date.getDate():date.getDate())));
- }
- };
- ///import core
- ///import plugins\paragraph.js
- ///commands 段间距
- ///commandsName RowSpacingBottom,RowSpacingTop
- ///commandsTitle 段间距
- /**
- * @description 设置段前距,段后距
- * @name baidu.editor.execCommand
- * @param {String} cmdName rowspacing设置段间距
- * @param {String} value 值,以px为单位
- * @param {String} dir top或bottom段前后段后
- * @author zhanyi
- */
- UE.plugins['rowspacing'] = function(){
- var me = this;
- me.setOpt({
- 'rowspacingtop':['5', '10', '15', '20', '25'],
- 'rowspacingbottom':['5', '10', '15', '20', '25']
- });
- me.commands['rowspacing'] = {
- execCommand : function( cmdName,value,dir ) {
- this.execCommand('paragraph','p',{style:'margin-'+dir+':'+value + 'px'});
- return true;
- },
- queryCommandValue : function(cmdName,dir) {
- var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node) }),
- value;
- //trace:1026
- if(pN){
- value = domUtils.getComputedStyle(pN,'margin-'+dir).replace(/[^\d]/g,'');
- return !value ? 0 : value;
- }
- return 0;
- }
- };
- };
- ///import core
- ///import plugins\paragraph.js
- ///commands 行间距
- ///commandsName LineHeight
- ///commandsTitle 行间距
- /**
- * @description 设置行内间距
- * @name baidu.editor.execCommand
- * @param {String} cmdName lineheight设置行内间距
- * @param {String} value 值
- * @author zhuwenxuan
- */
- UE.plugins['lineheight'] = function(){
- var me = this;
- me.setOpt({'lineheight':['1', '1.5','1.75','2', '3', '4', '5']});
- me.commands['lineheight'] = {
- execCommand : function( cmdName,value ) {
- this.execCommand('paragraph','p',{style:'line-height:'+ (value == "1" ? "normal" : value + 'em') });
- return true;
- },
- queryCommandValue : function() {
- var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node)});
- if(pN){
- var value = domUtils.getComputedStyle(pN,'line-height');
- return value == 'normal' ? 1 : value.replace(/[^\d.]*/ig,"");
- }
- }
- };
- };
- ///import core
- ///commands 清空文档
- ///commandsName ClearDoc
- ///commandsTitle 清空文档
- /**
- *
- * 清空文档
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName cleardoc清空文档
- */
- UE.commands['cleardoc'] = {
- execCommand : function( cmdName) {
- var me = this,
- enterTag = me.options.enterTag,
- range = me.selection.getRange();
- if(enterTag == "br"){
- me.body.innerHTML = "<br/>";
- range.setStart(me.body,0).setCursor();
- }else{
- me.body.innerHTML = "<p>"+(ie ? "" : "<br/>")+"</p>";
- range.setStart(me.body.firstChild,0).setCursor(false,true);
- }
- me.fireEvent("clearDoc");
- }
- };
- ///import core
- ///commands 锚点
- ///commandsName Anchor
- ///commandsTitle 锚点
- ///commandsDialog dialogs\anchor
- /**
- * 锚点
- * @function
- * @name baidu.editor.execCommands
- * @param {String} cmdName cmdName="anchor"插入锚点
- */
- UE.plugins['anchor'] = function (){
- var me = this;
- me.ready(function(){
- utils.cssRule('anchor',
- '.anchorclass{background: url(\'' + me.options.UEDITOR_HOME_URL + 'themes/default/images/anchor.gif\') no-repeat scroll left center transparent;border: 1px dotted #0000FF;cursor: auto;display: inline-block;height: 16px;width: 15px;}',me.document)
- });
- me.commands['anchor'] = {
- execCommand:function (cmd, name) {
- var range = this.selection.getRange(),img = range.getClosedNode();
- if (img && img.getAttribute('anchorname')) {
- if (name) {
- img.setAttribute('anchorname', name);
- } else {
- range.setStartBefore(img).setCursor();
- domUtils.remove(img);
- }
- } else {
- if (name) {
- //只在选区的开始插入
- var anchor = this.document.createElement('img');
- range.collapse(true);
- domUtils.setAttributes(anchor,{
- 'anchorname':name,
- 'class':'anchorclass'
- });
- range.insertNode(anchor).setStartAfter(anchor).setCursor(false,true);
- }
- }
- }
- };
- };
- ///import core
- ///commands 字数统计
- ///commandsName WordCount,wordCount
- ///commandsTitle 字数统计
- /**
- * Created by JetBrains WebStorm.
- * User: taoqili
- * Date: 11-9-7
- * Time: 下午8:18
- * To change this template use File | Settings | File Templates.
- */
- UE.plugins['wordcount'] = function(){
- var me = this;
- me.addListener('contentchange',function(){
- me.fireEvent('wordcount')
- });
- var timer;
- me.addListener('keyup',function(){
- clearTimeout(timer);
- var me = this;
- timer = setTimeout(function(){
- me.fireEvent('wordcount')
- },200)
- });
- };
- ///import core
- ///commands 添加分页功能
- ///commandsName PageBreak
- ///commandsTitle 分页
- /**
- * @description 添加分页功能
- * @author zhanyi
- */
- UE.plugins['pagebreak'] = function () {
- var me = this,
- notBreakTags = ['td'];
- function fillNode(node){
- if(domUtils.isEmptyBlock(node)){
- var firstChild = node.firstChild,tmpNode;
- while(firstChild && firstChild.nodeType == 1 && domUtils.isEmptyBlock(firstChild)){
- tmpNode = firstChild;
- firstChild = firstChild.firstChild;
- }
- !tmpNode && (tmpNode = node);
- domUtils.fillNode(me.document,tmpNode);
- }
- }
- //分页符样式添加
- me.ready(function(){
- utils.cssRule('pagebreak','.pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}',me.document);
- });
- function isHr(node){
- return node && node.nodeType == 1 && node.tagName == 'HR' && node.className == 'pagebreak';
- }
- me.commands['pagebreak'] = {
- execCommand:function () {
- var range = me.selection.getRange(),hr = me.document.createElement('hr');
- domUtils.setAttributes(hr,{
- 'class' : 'pagebreak',
- noshade:"noshade",
- size:"5"
- });
- domUtils.unSelectable(hr);
- //table单独处理
- var node = domUtils.findParentByTagName(range.startContainer, notBreakTags, true),
- parents = [], pN;
- if (node) {
- switch (node.tagName) {
- case 'TD':
- pN = node.parentNode;
- if (!pN.previousSibling) {
- var table = domUtils.findParentByTagName(pN, 'table');
- // var tableWrapDiv = table.parentNode;
- // if(tableWrapDiv && tableWrapDiv.nodeType == 1
- // && tableWrapDiv.tagName == 'DIV'
- // && tableWrapDiv.getAttribute('dropdrag')
- // ){
- // domUtils.remove(tableWrapDiv,true);
- // }
- table.parentNode.insertBefore(hr, table);
- parents = domUtils.findParents(hr, true);
- } else {
- pN.parentNode.insertBefore(hr, pN);
- parents = domUtils.findParents(hr);
- }
- pN = parents[1];
- if (hr !== pN) {
- domUtils.breakParent(hr, pN);
- }
- //table要重写绑定一下拖拽
- me.fireEvent('afteradjusttable',me.document);
- }
- } else {
- if (!range.collapsed) {
- range.deleteContents();
- var start = range.startContainer;
- while ( !domUtils.isBody(start) && domUtils.isBlockElm(start) && domUtils.isEmptyNode(start)) {
- range.setStartBefore(start).collapse(true);
- domUtils.remove(start);
- start = range.startContainer;
- }
- }
- range.insertNode(hr);
- var pN = hr.parentNode, nextNode;
- while (!domUtils.isBody(pN)) {
- domUtils.breakParent(hr, pN);
- nextNode = hr.nextSibling;
- if (nextNode && domUtils.isEmptyBlock(nextNode)) {
- domUtils.remove(nextNode);
- }
- pN = hr.parentNode;
- }
- nextNode = hr.nextSibling;
- var pre = hr.previousSibling;
- if(isHr(pre)){
- domUtils.remove(pre);
- }else{
- pre && fillNode(pre);
- }
- if(!nextNode){
- var p = me.document.createElement('p');
- hr.parentNode.appendChild(p);
- domUtils.fillNode(me.document,p);
- range.setStart(p,0).collapse(true);
- }else{
- if(isHr(nextNode)){
- domUtils.remove(nextNode);
- }else{
- fillNode(nextNode);
- }
- range.setEndAfter(hr).collapse(false);
- }
- range.select(true);
- }
- }
- };
- };
- ///import core
- ///commands 本地图片引导上传
- ///commandsName WordImage
- ///commandsTitle 本地图片引导上传
- ///commandsDialog dialogs\wordimage
- UE.plugins["wordimage"] = function(){
- var me = this,
- images;
- me.commands['wordimage'] = {
- execCommand : function() {
- images = domUtils.getElementsByTagName(me.document.body,"img");
- var urlList = [];
- for(var i=0,ci;ci=images[i++];){
- var url=ci.getAttribute("word_img");
- url && urlList.push(url);
- }
- if(images.length){
- this["word_img"] = urlList;
- }
- },
- queryCommandState: function(){
- images = domUtils.getElementsByTagName(me.document.body,"img");
- for(var i=0,ci;ci =images[i++];){
- if(ci.getAttribute("word_img")){
- return 1;
- }
- }
- return -1;
- }
- };
- };
- ///import core
- ///commands 撤销和重做
- ///commandsName Undo,Redo
- ///commandsTitle 撤销,重做
- /**
- * @description 回退
- * @author zhanyi
- */
- UE.plugins['undo'] = function () {
- var me = this,
- maxUndoCount = me.options.maxUndoCount || 20,
- maxInputCount = me.options.maxInputCount || 20,
- fillchar = new RegExp(domUtils.fillChar + '|<\/hr>', 'gi');// ie会产生多余的</hr>
- function compareAddr(indexA, indexB) {
- if (indexA.length != indexB.length)
- return 0;
- for (var i = 0, l = indexA.length; i < l; i++) {
- if (indexA[i] != indexB[i])
- return 0
- }
- return 1;
- }
- function compareRangeAddress(rngAddrA, rngAddrB) {
- if (rngAddrA.collapsed != rngAddrB.collapsed) {
- return 0;
- }
- if (!compareAddr(rngAddrA.startAddress, rngAddrB.startAddress) || !compareAddr(rngAddrA.endAddress, rngAddrB.endAddress)) {
- return 0;
- }
- return 1;
- }
- function adjustContent(cont) {
- var specialAttr = /\b(?:href|src|name)="[^"]*?"/gi;
- return cont.replace(specialAttr, '')
- .replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (a, b, c) {
- return b.toLowerCase() + '=' + c.replace(/['"]/g, '').toLowerCase()
- })
- .replace(/(<[\w\-]+)|([\w\-]+>)/gi, function (a, b, c) {
- return (b || c).toLowerCase()
- });
- }
- function UndoManager() {
- this.list = [];
- this.index = 0;
- this.hasUndo = false;
- this.hasRedo = false;
- this.undo = function () {
- if (this.hasUndo) {
- var currentScene = this.getScene(),
- lastScene = this.list[this.index],
- lastContent = adjustContent(lastScene.content),
- currentContent = adjustContent(currentScene.content);
- if (lastContent != currentContent) {
- this.save();
- }
- if (!this.list[this.index - 1] && this.list.length == 1) {
- this.reset();
- return;
- }
- while (this.list[this.index].content == this.list[this.index - 1].content) {
- this.index--;
- if (this.index == 0) {
- return this.restore(0);
- }
- }
- this.restore(--this.index);
- }
- };
- this.redo = function () {
- if (this.hasRedo) {
- while (this.list[this.index].content == this.list[this.index + 1].content) {
- this.index++;
- if (this.index == this.list.length - 1) {
- return this.restore(this.index);
- }
- }
- this.restore(++this.index);
- }
- };
- this.restore = function () {
- var scene = this.list[this.index];
- //trace:873
- //去掉展位符
- me.document.body.innerHTML = scene.content.replace(fillchar, '');
- //处理undo后空格不展位的问题
- if (browser.ie) {
- utils.each(domUtils.getElementsByTagName(me.document,'td th caption p'),function(node){
- if(domUtils.isEmptyNode(node)){
- domUtils.fillNode(me.document, node);
- }
- })
- }
- new dom.Range(me.document).moveToAddress(scene.address).select();
- this.update();
- this.clearKey();
- //不能把自己reset了
- me.fireEvent('reset', true);
- };
- this.getScene = function (notSetCursor) {
- var rng = me.selection.getRange(),
- restoreAddress = rng.createAddress(),
- rngAddress = rng.createAddress(false,true);
- me.fireEvent('beforegetscene');
- var cont = me.body.innerHTML.replace(fillchar, '');
- browser.ie && (cont = cont.replace(/> </g, '><').replace(/\s*</g, '<').replace(/>\s*/g, '>'));
- me.fireEvent('aftergetscene');
- try{
- !notSetCursor && rng.moveToAddress(restoreAddress).select(true);
- }catch(e){}
- return {
- address:rngAddress,
- content:cont
- }
- };
- this.save = function (notCompareRange,notSetCursor) {
- var currentScene = this.getScene(notSetCursor),
- lastScene = this.list[this.index];
- //内容相同位置相同不存
- if (lastScene && lastScene.content == currentScene.content &&
- ( notCompareRange ? 1 : compareRangeAddress(lastScene.address, currentScene.address) )
- ) {
- return;
- }
- this.list = this.list.slice(0, this.index + 1);
- this.list.push(currentScene);
- //如果大于最大数量了,就把最前的剔除
- if (this.list.length > maxUndoCount) {
- this.list.shift();
- }
- this.index = this.list.length - 1;
- this.clearKey();
- //跟新undo/redo状态
- this.update();
- };
- this.update = function () {
- this.hasRedo = !!this.list[this.index + 1];
- this.hasUndo = !!this.list[this.index - 1];
- };
- this.reset = function () {
- this.list = [];
- this.index = 0;
- this.hasUndo = false;
- this.hasRedo = false;
- this.clearKey();
- };
- this.clearKey = function () {
- keycont = 0;
- lastKeyCode = null;
- };
- }
- me.undoManger = new UndoManager();
- function saveScene() {
- this.undoManger.save();
- }
- me.addListener('saveScene', function () {
- me.undoManger.save();
- });
- me.addListener('beforeexeccommand', saveScene);
- me.addListener('afterexeccommand', saveScene);
- me.addListener('reset', function (type, exclude) {
- if (!exclude) {
- me.undoManger.reset();
- }
- });
- me.commands['redo'] = me.commands['undo'] = {
- execCommand:function (cmdName) {
- me.undoManger[cmdName]();
- },
- queryCommandState:function (cmdName) {
- return me.undoManger['has' + (cmdName.toLowerCase() == 'undo' ? 'Undo' : 'Redo')] ? 0 : -1;
- },
- notNeedUndo:1
- };
- var keys = {
- // /*Backspace*/ 8:1, /*Delete*/ 46:1,
- /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1,
- 37:1, 38:1, 39:1, 40:1,
- 13:1 /*enter*/
- },
- keycont = 0,
- lastKeyCode;
- //输入法状态下不计算字符数
- var inputType = false;
- me.addListener('ready', function () {
- domUtils.on(me.body, 'compositionstart', function () {
- inputType = true;
- });
- domUtils.on(me.body, 'compositionend', function () {
- inputType = false;
- })
- });
- //快捷键
- me.addshortcutkey({
- "Undo":"ctrl+90", //undo
- "Redo":"ctrl+89" //redo
- });
- me.addListener('keydown', function (type, evt) {
- var keyCode = evt.keyCode || evt.which;
- if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) {
- if (inputType)
- return;
- if (me.undoManger.list.length == 0 || ((keyCode == 8 || keyCode == 46) && lastKeyCode != keyCode)) {
- me.fireEvent('contentchange');
- me.undoManger.save(true,true);
- lastKeyCode = keyCode;
- return;
- }
- //trace:856
- //修正第一次输入后,回退,再输入要到keycont>maxInputCount才能在回退的问题
- if (me.undoManger.list.length == 2 && me.undoManger.index == 0 && keycont == 0) {
- me.undoManger.list.splice(1, 1);
- me.undoManger.update();
- }
- lastKeyCode = keyCode;
- keycont++;
- if (keycont >= maxInputCount || me.undoManger.mousedown) {
- if (me.selection.getRange().collapsed)
- me.fireEvent('contentchange');
- me.undoManger.save(false,true);
- me.undoManger.mousedown = false;
- }
- }
- });
- me.addListener('mousedown',function(){
- me.undoManger.mousedown = true;
- })
- };
- ///import core
- ///import plugins/inserthtml.js
- ///import plugins/undo.js
- ///import plugins/serialize.js
- ///commands 粘贴
- ///commandsName PastePlain
- ///commandsTitle 纯文本粘贴模式
- /*
- ** @description 粘贴
- * @author zhanyi
- */
- (function() {
- function getClipboardData( callback ) {
- var doc = this.document;
- if ( doc.getElementById( 'baidu_pastebin' ) ) {
- return;
- }
- var range = this.selection.getRange(),
- bk = range.createBookmark(),
- //创建剪贴的容器div
- pastebin = doc.createElement( 'div' );
- pastebin.id = 'baidu_pastebin';
- // Safari 要求div必须有内容,才能粘贴内容进来
- browser.webkit && pastebin.appendChild( doc.createTextNode( domUtils.fillChar + domUtils.fillChar ) );
- doc.body.appendChild( pastebin );
- //trace:717 隐藏的span不能得到top
- //bk.start.innerHTML = ' ';
- bk.start.style.display = '';
- pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" +
- //要在现在光标平行的位置加入,否则会出现跳动的问题
- domUtils.getXY( bk.start ).y + 'px';
- range.selectNodeContents( pastebin ).select( true );
- setTimeout( function() {
- if (browser.webkit) {
- for(var i=0,pastebins = doc.querySelectorAll('#baidu_pastebin'),pi;pi=pastebins[i++];){
- if(domUtils.isEmptyNode(pi)){
- domUtils.remove(pi);
- }else{
- pastebin = pi;
- break;
- }
- }
- }
- try{
- pastebin.parentNode.removeChild(pastebin);
- }catch(e){}
- range.moveToBookmark( bk ).select(true);
- callback( pastebin );
- }, 0 );
- }
- UE.plugins['paste'] = function() {
- var me = this;
- var word_img_flag = {flag:""};
- var pasteplain = me.options.pasteplain === true;
- var modify_num = {flag:""};
- me.commands['pasteplain'] = {
- queryCommandState: function (){
- return pasteplain;
- },
- execCommand: function (){
- pasteplain = !pasteplain|0;
- },
- notNeedUndo : 1
- };
- var txtContent,htmlContent,address;
- function filter(div){
- var html;
- if ( div.firstChild ) {
- //去掉cut中添加的边界值
- var nodes = domUtils.getElementsByTagName(div,'span');
- for(var i=0,ni;ni=nodes[i++];){
- if(ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end'){
- domUtils.remove(ni);
- }
- }
- if(browser.webkit){
- var brs = div.querySelectorAll('div br');
- for(var i=0,bi;bi=brs[i++];){
- var pN = bi.parentNode;
- if(pN.tagName == 'DIV' && pN.childNodes.length ==1){
- pN.innerHTML = '<p><br/></p>';
- domUtils.remove(pN);
- }
- }
- var divs = div.querySelectorAll('#baidu_pastebin');
- for(var i=0,di;di=divs[i++];){
- var tmpP = me.document.createElement('p');
- di.parentNode.insertBefore(tmpP,di);
- while(di.firstChild){
- tmpP.appendChild(di.firstChild);
- }
- domUtils.remove(di);
- }
- var metas = div.querySelectorAll('meta');
- for(var i=0,ci;ci=metas[i++];){
- domUtils.remove(ci);
- }
- var brs = div.querySelectorAll('br');
- for(i=0;ci=brs[i++];){
- if(/^apple-/.test(ci)){
- domUtils.remove(ci);
- }
- }
- utils.each(domUtils.getElementsByTagName(div,'span',function(node){
- if(node.style.cssText){
- node.style.cssText = node.style.cssText.replace(/white-space[^;]+;/g,'');
- if(!node.style.cssText){
- domUtils.removeAttributes(node,'style');
- if(domUtils.hasNoAttributes(node)){
- return 1
- }
- }
- }
- return 0
- }),function(si){
- domUtils.remove(si,true)
- })
- }
- if(browser.gecko){
- var dirtyNodes = div.querySelectorAll('[_moz_dirty]');
- for(i=0;ci=dirtyNodes[i++];){
- ci.removeAttribute( '_moz_dirty' );
- }
- }
- if(!browser.ie ){
- var spans = div.querySelectorAll('span.Apple-style-span');
- for(var i=0,ci;ci=spans[i++];){
- domUtils.remove(ci,true);
- }
- }
- //ie下使用innerHTML会产生多余的\r\n字符,也会产生 这里过滤掉
- html = div.innerHTML.replace(/>(?:(\s| )*?)</g,'><');
- var f = me.serialize;
- if(f){
- //如果过滤出现问题,捕获它,直接插入内容,避免出现错误导致粘贴整个失败
- try{
- html = UE.filterWord(html);
- var node = f.transformInput(
- f.parseHTML(
- //todo: 暂时不走dtd的过滤
- html//, true
- ),word_img_flag
- );
- //trace:924
- //纯文本模式也要保留段落
- node = f.filter(node,pasteplain ? {
- whiteList: {
- 'p': {'br':1,'BR':1,$:{}},
- 'br':{'$':{}},
- 'div':{'br':1,'BR':1,'$':{}},
- 'li':{'$':{}},
- 'tr':{'td':1,'$':{}},
- 'td':{'$':{}}
- },
- blackList: {
- 'style':1,
- 'script':1,
- 'object':1
- }
- } : null, !pasteplain ? modify_num : null);
- if(browser.webkit){
- var length = node.children.length,
- child;
- while((child = node.children[length-1]) && child.tag == 'br'){
- node.children.splice(length-1,1);
- length = node.children.length;
- }
- }
- html = f.toHTML(node,pasteplain);
- txtContent = f.filter(node,{
- whiteList: {
- 'p': {'br':1,'BR':1,$:{}},
- 'br':{'$':{}},
- 'div':{'br':1,'BR':1,'$':{},'table':1,'ul':1,'ol':1},
- 'li':{'$':{}},
- 'ul':{'li':1,'$':{}},
- 'ol':{'li':1,'$':{}},
- 'tr':{'td':1,'$':{}},
- 'td':{'$':{}},
- 'table': {'tr':1,'tbody':1,'td':1,'$':{}},
- 'tbody': {'tr':1,'td':1,'$':{}},
- h1:{'$':{}},h2:{'$':{}},h3:{'$':{}},h4:{'$':{}},h5:{'$':{}},h6:{'$':{}}
- },
- blackList: {
- 'style':1,
- 'script':1,
- 'object':1
- }
- });
- txtContent = f.toHTML(txtContent,true)
- }catch(e){}
- }
- //自定义的处理
- html = {'html':html,'txtContent':txtContent};
- me.fireEvent('beforepaste',html);
- //不用在走过滤了
- if(html.html){
- htmlContent = html.html;
- address = me.selection.getRange().createAddress(true);
- me.execCommand( 'insertHtml',htmlContent,true);
- me.fireEvent("afterpaste");
- }
- }
- }
- me.addListener('pasteTransfer',function(cmd,plainType){
- if(address && txtContent && htmlContent && txtContent != htmlContent){
- var range = me.selection.getRange();
- range.moveToAddress(address,true).deleteContents();
- range.select(true);
- me.__hasEnterExecCommand = true;
- var html = htmlContent;
- if(plainType === 2){
- html = html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi,function(a,b,tagName,attrs){
- tagName = tagName.toLowerCase();
- if({img:1}[tagName]){
- return a;
- }
- attrs = attrs.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi,function(str,atr,val){
- if({
- 'src':1,
- 'href':1,
- 'name':1
- }[atr.toLowerCase()]){
- return atr + '=' + val + ' '
- }
- return ''
- });
- if({
- 'span':1,
- 'div':1
- }[tagName]){
- return ''
- }else{
- return '<' + b + tagName + ' ' + utils.trim(attrs) + '>'
- }
- });
- }else if(plainType){
- html = txtContent;
- }
- me.execCommand('inserthtml',html,true);
- me.__hasEnterExecCommand = false;
- var tmpAddress = me.selection.getRange().createAddress(true);
- address.endAddress = tmpAddress.startAddress;
- }
- });
- me.addListener('ready',function(){
- domUtils.on(me.body,'cut',function(){
- var range = me.selection.getRange();
- if(!range.collapsed && me.undoManger){
- me.undoManger.save();
- }
- });
- //ie下beforepaste在点击右键时也会触发,所以用监控键盘才处理
- domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste',function(e){
- if((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')){
- return;
- }
- getClipboardData.call( me, function( div ) {
- filter(div);
- } );
- });
- });
- };
- })();
- ///import core
- ///commands 有序列表,无序列表
- ///commandsName InsertOrderedList,InsertUnorderedList
- ///commandsTitle 有序列表,无序列表
- /**
- * 有序列表
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName insertorderlist插入有序列表
- * @param {String} style 值为:decimal,lower-alpha,lower-roman,upper-alpha,upper-roman
- * @author zhanyi
- */
- /**
- * 无序链接
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName insertunorderlist插入无序列表
- * * @param {String} style 值为:circle,disc,square
- * @author zhanyi
- */
- UE.plugins['list'] = function () {
- var me = this,
- notExchange = {
- 'TD':1,
- 'PRE':1,
- 'BLOCKQUOTE':1
- };
- var customStyle = {
- 'cn' : 'cn-1-',
- 'cn1' : 'cn-2-',
- 'cn2' : 'cn-3-',
- 'num': 'num-1-',
- 'num1' : 'num-2-',
- 'num2' : 'num-3-',
- 'dash' : 'dash',
- 'dot':'dot'
- };
- me.setOpt( {
- 'insertorderedlist':{
- 'num':'',
- 'num1':'',
- 'num2':'',
- 'cn':'',
- 'cn1':'',
- 'cn2':'',
- 'decimal':'',
- 'lower-alpha':'',
- 'lower-roman':'',
- 'upper-alpha':'',
- 'upper-roman':''
- },
- 'insertunorderedlist':{
- 'circle':'',
- 'disc':'',
- 'square':'',
- 'dash' : '',
- 'dot':''
- },
- listDefaultPaddingLeft : '30',
- listiconpath : 'http://bs.baidu.com/listicon/',
- maxListLevel : 3//-1不限制
- } );
- var liiconpath = me.options.listiconpath;
- //根据用户配置,调整customStyle
- for(var s in customStyle){
- if(!me.options.insertorderedlist.hasOwnProperty(s) && !me.options.insertunorderedlist.hasOwnProperty(s)){
- delete customStyle[s];
- }
- }
- me.ready(function () {
- var customCss = [];
- for(var p in customStyle){
- if(p == 'dash' || p == 'dot'){
- customCss.push('li.list-' + customStyle[p] + '{background-image:url(' + liiconpath +customStyle[p]+'.gif)}');
- customCss.push('ul.custom_'+p+'{list-style:none;}ul.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}');
- }else{
- for(var i= 0;i<99;i++){
- customCss.push('li.list-' + customStyle[p] + i + '{background-image:url(' + liiconpath + 'list-'+customStyle[p] + i + '.gif)}')
- }
- customCss.push('ol.custom_'+p+'{list-style:none;}ol.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}');
- }
- switch(p){
- case 'cn':
- customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}');
- customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');
- customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}');
- break;
- case 'cn1':
- customCss.push('li.list-'+p+'-paddingleft-1{padding-left:30px}');
- customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');
- customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}');
- break;
- case 'cn2':
- customCss.push('li.list-'+p+'-paddingleft-1{padding-left:40px}');
- customCss.push('li.list-'+p+'-paddingleft-2{padding-left:55px}');
- customCss.push('li.list-'+p+'-paddingleft-3{padding-left:68px}');
- break;
- case 'num':
- case 'num1':
- customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}');
- break;
- case 'num2':
- customCss.push('li.list-'+p+'-paddingleft-1{padding-left:35px}');
- customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');
- break;
- case 'dash':
- customCss.push('li.list-'+p+'-paddingleft{padding-left:35px}');
- break;
- case 'dot':
- customCss.push('li.list-'+p+'-paddingleft{padding-left:20px}');
- }
- }
- customCss.push('.list-paddingleft-1{padding-left:0}');
- customCss.push('.list-paddingleft-2{padding-left:'+me.options.listDefaultPaddingLeft+'px}');
- customCss.push('.list-paddingleft-3{padding-left:'+me.options.listDefaultPaddingLeft*2+'px}');
- //如果不给宽度会在自定应样式里出现滚动条
- utils.cssRule('list', 'ol,ul{margin:0;pading:0;'+(browser.ie ? '' : 'width:95%')+'}li{clear:both;}'+customCss.join('\n'), me.document);
- });
- function getStyle(node){
- var cls = node.className;
- if(domUtils.hasClass(node,/custom_/)){
- return cls.match(/custom_(\w+)/)[1]
- }
- return ''
- }
- // function checkCustomStyle(list){
- // if(domUtils.hasClass(list,/custom_/)){
- // return ''
- // }
- // var style;
- // utils.each(list.childNodes,function(li){
- // if(li.tagName == 'LI'){
- // if(domUtils.hasClass(li,/list-/)){
- // var tmpStyle = li.className.match(/list-(\w+)-(\d+)?/);
- // style = tmpStyle[1]+(tmpStyle[2] && tmpStyle[2] != '1'? tmpStyle[2]:'');
- // return false
- // }
- // }
- // })
- // return style;
- // }
- //调整索引标签
- me.addListener('contentchange',function(){
- utils.each(domUtils.getElementsByTagName(me.document,'ol ul'),function(node){
- if(!domUtils.inDoc(node,me.document))
- return;
- // var style;
- // if(style = checkCustomStyle(node)){
- // node.className = 'custom_' + style;
- // }
- var index = 0,type = 2,parent = node.parentNode;
- if( domUtils.hasClass(node,/custom_/)){
- if(!(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/))){
- type = 1;
- }
- }else{
- if(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/)){
- type = 3;
- }
- }
- style = domUtils.getStyle(node, 'list-style-type');
- node.style.cssText = style ? 'list-style-type:' + style : '';
- node.className = utils.trim(node.className.replace(/list-paddingleft-\w+/,'')) + ' list-paddingleft-' + type;
- utils.each(domUtils.getElementsByTagName(node,'li'),function(li){
- li.style.cssText && (li.style.cssText = '');
- if(!li.firstChild){
- domUtils.remove(li);
- return;
- }
- if(li.parentNode !== node){
- return;
- }
- index++;
- if(domUtils.hasClass(node,/custom_/) ){
- var paddingLeft = 1,currentStyle = getStyle(node);
- if(node.tagName == 'OL'){
- if(currentStyle){
- switch(currentStyle){
- case 'cn' :
- case 'cn1':
- case 'cn2':
- if(index > 10 && (index % 10 == 0 || index > 10 && index < 20)){
- paddingLeft = 2
- }else if(index > 20){
- paddingLeft = 3
- }
- break;
- case 'num2' :
- if(index > 9){
- paddingLeft = 2
- }
- }
- }
- li.className = 'list-'+customStyle[currentStyle]+ index + ' ' + 'list-'+currentStyle+'-paddingleft-' + paddingLeft;
- }else{
- li.className = 'list-'+customStyle[currentStyle] + ' ' + 'list-'+currentStyle+'-paddingleft';
- }
- }else{
- li.className = li.className.replace(/list-[\w\-]+/gi,'');
- }
- var className = li.getAttribute('class');
- if(className !== null && !className.replace(/\s/g,'')){
- domUtils.removeAttributes(li,'class')
- }
- });
- adjustList(node,node.tagName.toLowerCase(),getStyle(node)||domUtils.getStyle(node, 'list-style-type'),true)
- })
- });
- function adjustList(list, tag, style,ignoreEmpty) {
- var nextList = list.nextSibling;
- if (nextList && nextList.nodeType == 1 && nextList.tagName.toLowerCase() == tag && (getStyle(nextList) || domUtils.getStyle(nextList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) {
- domUtils.moveChild(nextList, list);
- if (nextList.childNodes.length == 0) {
- domUtils.remove(nextList);
- }
- }
- if(nextList && domUtils.isFillChar(nextList)){
- domUtils.remove(nextList);
- }
- var preList = list.previousSibling;
- if (preList && preList.nodeType == 1 && preList.tagName.toLowerCase() == tag && (getStyle(preList) || domUtils.getStyle(preList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) {
- domUtils.moveChild(list, preList);
- }
- if(preList && domUtils.isFillChar(preList)){
- domUtils.remove(preList);
- }
- !ignoreEmpty && domUtils.isEmptyBlock(list) && domUtils.remove(list);
- }
- function setListStyle(list,style){
- if(customStyle[style]){
- list.className = 'custom_' + style;
- }
- try{
- domUtils.setStyle(list, 'list-style-type', style);
- }catch(e){}
- }
- function clearEmptySibling(node) {
- var tmpNode = node.previousSibling;
- if (tmpNode && domUtils.isEmptyBlock(tmpNode)) {
- domUtils.remove(tmpNode);
- }
- tmpNode = node.nextSibling;
- if (tmpNode && domUtils.isEmptyBlock(tmpNode)) {
- domUtils.remove(tmpNode);
- }
- }
- me.addListener('keydown', function (type, evt) {
- function preventAndSave() {
- evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);
- me.fireEvent('contentchange');
- me.undoManger && me.undoManger.save();
- }
- function findList(node,filterFn){
- while(node && !domUtils.isBody(node)){
- if(filterFn(node)){
- return null
- }
- if(node.nodeType == 1 && /[ou]l/i.test(node.tagName)){
- return node;
- }
- node = node.parentNode;
- }
- return null;
- }
- var keyCode = evt.keyCode || evt.which;
- if (keyCode == 13 && !evt.shiftKey) {//回车
- var range = me.selection.getRange(),
- start = findList(range.startContainer,function (node) {
- return node.tagName == 'TABLE';
- }),
- end = range.collapsed ? start : findList(range.endContainer,function (node) {
- return node.tagName == 'TABLE';
- });
- if (start && end && start === end) {
- if (!range.collapsed) {
- start = domUtils.findParentByTagName(range.startContainer, 'li', true);
- end = domUtils.findParentByTagName(range.endContainer, 'li', true);
- if (start && end && start === end) {
- range.deleteContents();
- li = domUtils.findParentByTagName(range.startContainer, 'li', true);
- if (li && domUtils.isEmptyBlock(li)) {
- pre = li.previousSibling;
- next = li.nextSibling;
- p = me.document.createElement('p');
- domUtils.fillNode(me.document, p);
- parentList = li.parentNode;
- if (pre && next) {
- range.setStart(next, 0).collapse(true).select(true);
- domUtils.remove(li);
- } else {
- if (!pre && !next || !pre) {
- parentList.parentNode.insertBefore(p, parentList);
- } else {
- li.parentNode.parentNode.insertBefore(p, parentList.nextSibling);
- }
- domUtils.remove(li);
- if (!parentList.firstChild) {
- domUtils.remove(parentList);
- }
- range.setStart(p, 0).setCursor();
- }
- preventAndSave();
- return;
- }
- } else {
- var tmpRange = range.cloneRange(),
- bk = tmpRange.collapse(false).createBookmark();
- range.deleteContents();
- tmpRange.moveToBookmark(bk);
- var li = domUtils.findParentByTagName(tmpRange.startContainer, 'li', true);
- clearEmptySibling(li);
- tmpRange.select();
- preventAndSave();
- return;
- }
- }
- li = domUtils.findParentByTagName(range.startContainer, 'li', true);
- if (li) {
- if (domUtils.isEmptyBlock(li)) {
- bk = range.createBookmark();
- var parentList = li.parentNode;
- if (li !== parentList.lastChild) {
- domUtils.breakParent(li, parentList);
- clearEmptySibling(li);
- } else {
- parentList.parentNode.insertBefore(li, parentList.nextSibling);
- if (domUtils.isEmptyNode(parentList)) {
- domUtils.remove(parentList);
- }
- }
- //嵌套不处理
- if (!dtd.$list[li.parentNode.tagName]) {
- if (!domUtils.isBlockElm(li.firstChild)) {
- p = me.document.createElement('p');
- li.parentNode.insertBefore(p, li);
- while (li.firstChild) {
- p.appendChild(li.firstChild);
- }
- domUtils.remove(li);
- } else {
- domUtils.remove(li, true);
- }
- }
- range.moveToBookmark(bk).select();
- } else {
- var first = li.firstChild;
- if (!first || !domUtils.isBlockElm(first)) {
- var p = me.document.createElement('p');
- !li.firstChild && domUtils.fillNode(me.document, p);
- while (li.firstChild) {
- p.appendChild(li.firstChild);
- }
- li.appendChild(p);
- first = p;
- }
- var span = me.document.createElement('span');
- range.insertNode(span);
- domUtils.breakParent(span, li);
- var nextLi = span.nextSibling;
- first = nextLi.firstChild;
- if (!first) {
- p = me.document.createElement('p');
- domUtils.fillNode(me.document, p);
- nextLi.appendChild(p);
- first = p;
- }
- if (domUtils.isEmptyNode(first)) {
- first.innerHTML = '';
- domUtils.fillNode(me.document, first);
- }
- range.setStart(first, 0).collapse(true).shrinkBoundary().select();
- domUtils.remove(span);
- var pre = nextLi.previousSibling;
- if (pre && domUtils.isEmptyBlock(pre)) {
- pre.innerHTML = '<p></p>';
- domUtils.fillNode(me.document, pre.firstChild);
- }
- }
- // }
- preventAndSave();
- }
- }
- }
- if (keyCode == 8) {
- //修中ie中li下的问题
- range = me.selection.getRange();
- if (range.collapsed && domUtils.isStartInblock(range)) {
- tmpRange = range.cloneRange().trimBoundary();
- li = domUtils.findParentByTagName(range.startContainer, 'li', true);
- //要在li的最左边,才能处理
- if (li && domUtils.isStartInblock(tmpRange)) {
- start = domUtils.findParentByTagName(range.startContainer, 'p', true);
- if (start && start !== li.firstChild) {
- var parentList = domUtils.findParentByTagName(start,['ol','ul']);
- domUtils.breakParent(start,parentList);
- clearEmptySibling(start);
- me.fireEvent('contentchange');
- range.setStart(start,0).setCursor(false,true);
- me.fireEvent('saveScene');
- domUtils.preventDefault(evt);
- return;
- }
- if (li && (pre = li.previousSibling)) {
- if (keyCode == 46 && li.childNodes.length) {
- return;
- }
- //有可能上边的兄弟节点是个2级菜单,要追加到2级菜单的最后的li
- if (dtd.$list[pre.tagName]) {
- pre = pre.lastChild;
- }
- me.undoManger && me.undoManger.save();
- first = li.firstChild;
- if (domUtils.isBlockElm(first)) {
- if (domUtils.isEmptyNode(first)) {
- // range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true);
- pre.appendChild(first);
- range.setStart(first, 0).setCursor(false, true);
- //first不是唯一的节点
- while (li.firstChild) {
- pre.appendChild(li.firstChild);
- }
- } else {
- span = me.document.createElement('span');
- range.insertNode(span);
- //判断pre是否是空的节点,如果是<p><br/></p>类型的空节点,干掉p标签防止它占位
- if (domUtils.isEmptyBlock(pre)) {
- pre.innerHTML = '';
- }
- domUtils.moveChild(li, pre);
- range.setStartBefore(span).collapse(true).select(true);
- domUtils.remove(span);
- }
- } else {
- if (domUtils.isEmptyNode(li)) {
- var p = me.document.createElement('p');
- pre.appendChild(p);
- range.setStart(p, 0).setCursor();
- // range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true);
- } else {
- range.setEnd(pre, pre.childNodes.length).collapse().select(true);
- while (li.firstChild) {
- pre.appendChild(li.firstChild);
- }
- }
- }
- domUtils.remove(li);
- me.fireEvent('contentchange');
- me.fireEvent('saveScene');
- domUtils.preventDefault(evt);
- return;
- }
- //trace:980
- if (li && !li.previousSibling) {
- var parentList = li.parentNode;
- var bk = range.createBookmark();
- if(domUtils.isTagNode(parentList.parentNode,'ol ul')){
- parentList.parentNode.insertBefore(li,parentList);
- if(domUtils.isEmptyNode(parentList)){
- domUtils.remove(parentList)
- }
- }else{
- while(li.firstChild){
- parentList.parentNode.insertBefore(li.firstChild,parentList);
- }
- domUtils.remove(li);
- if(domUtils.isEmptyNode(parentList)){
- domUtils.remove(parentList)
- }
- }
- range.moveToBookmark(bk).setCursor(false,true);
- me.fireEvent('contentchange');
- me.fireEvent('saveScene');
- domUtils.preventDefault(evt);
- return;
- }
- }
- }
- }
- });
- //处理tab键
- me.addListener('tabkeydown',function(){
- function listToArray(list){
- var arr = [];
- for(var p in list){
- arr.push(p)
- }
- return arr;
- }
- var range = me.selection.getRange(),
- listStyle = {
- 'OL':listToArray(me.options.insertorderedlist),
- 'UL':listToArray(me.options.insertunorderedlist)
- };
- //控制级数
- function checkLevel(li){
- if(me.options.maxListLevel != -1){
- var level = li.parentNode,levelNum = 0;
- while(/[ou]l/i.test(level.tagName)){
- levelNum++;
- level = level.parentNode;
- }
- if(levelNum >= me.options.maxListLevel){
- return true;
- }
- }
- }
- //只以开始为准
- //todo 后续改进
- var li = domUtils.findParentByTagName(range.startContainer, 'li', true);
- if(li){
- var bk;
- if(range.collapsed){
- if(checkLevel(li))
- return true;
- var parentLi = li.parentNode,
- list = me.document.createElement(parentLi.tagName),
- index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type'));
- index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1;
- var currentStyle = listStyle[list.tagName][index];
- setListStyle(list,currentStyle);
- if(domUtils.isStartInblock(range)){
- me.fireEvent('saveScene');
- bk = range.createBookmark();
- parentLi.insertBefore(list, li);
- list.appendChild(li);
- adjustList(list,list.tagName.toLowerCase(),currentStyle);
- me.fireEvent('contentchange');
- range.moveToBookmark(bk).select(true);
- return true;
- }
- }else{
- me.fireEvent('saveScene');
- bk = range.createBookmark();
- for(var i= 0,closeList,parents = domUtils.findParents(li),ci;ci=parents[i++];){
- if(domUtils.isTagNode(ci,'ol ul')){
- closeList = ci;
- break;
- }
- }
- var current = li;
- if(bk.end){
- while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){
- if(checkLevel(current)){
- current = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList});
- continue;
- }
- var parentLi = current.parentNode,
- list = me.document.createElement(parentLi.tagName),
- index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type'));
- var currentIndex = index + 1 == listStyle[list.tagName].length ? 0 : index + 1;
- var currentStyle = listStyle[list.tagName][currentIndex];
- setListStyle(list,currentStyle);
- parentLi.insertBefore(list, current);
- while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){
- li = current.nextSibling;
- list.appendChild(current);
- if(!li || domUtils.isTagNode(li,'ol ul')){
- if(li){
- while(li = li.firstChild){
- if(li.tagName == 'LI'){
- break;
- }
- }
- }else{
- li = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList});
- }
- break;
- }
- current = li;
- }
- adjustList(list,list.tagName.toLowerCase(),currentStyle);
- current = li;
- }
- }
- me.fireEvent('contentchange');
- range.moveToBookmark(bk).select();
- return true;
- }
- }
- });
- me.commands['insertorderedlist'] =
- me.commands['insertunorderedlist'] = {
- execCommand:function (command, style) {
- if (!style) {
- style = command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc';
- }
- var me = this,
- range = this.selection.getRange(),
- filterFn = function (node) {
- return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node);
- },
- tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul',
- frag = me.document.createDocumentFragment();
- //去掉是因为会出现选到末尾,导致adjustmentBoundary缩到ol/ul的位置
- //range.shrinkBoundary();//.adjustmentBoundary();
- range.adjustmentBoundary().shrinkBoundary();
- var bko = range.createBookmark(true),
- start = domUtils.findParentByTagName(me.document.getElementById(bko.start), 'li'),
- modifyStart = 0,
- end = domUtils.findParentByTagName(me.document.getElementById(bko.end), 'li'),
- modifyEnd = 0,
- startParent, endParent,
- list, tmp;
- if (start || end) {
- start && (startParent = start.parentNode);
- if (!bko.end) {
- end = start;
- }
- end && (endParent = end.parentNode);
- if (startParent === endParent) {
- while (start !== end) {
- tmp = start;
- start = start.nextSibling;
- if (!domUtils.isBlockElm(tmp.firstChild)) {
- var p = me.document.createElement('p');
- while (tmp.firstChild) {
- p.appendChild(tmp.firstChild);
- }
- tmp.appendChild(p);
- }
- frag.appendChild(tmp);
- }
- tmp = me.document.createElement('span');
- startParent.insertBefore(tmp, end);
- if (!domUtils.isBlockElm(end.firstChild)) {
- p = me.document.createElement('p');
- while (end.firstChild) {
- p.appendChild(end.firstChild);
- }
- end.appendChild(p);
- }
- frag.appendChild(end);
- domUtils.breakParent(tmp, startParent);
- if (domUtils.isEmptyNode(tmp.previousSibling)) {
- domUtils.remove(tmp.previousSibling);
- }
- if (domUtils.isEmptyNode(tmp.nextSibling)) {
- domUtils.remove(tmp.nextSibling)
- }
- var nodeStyle = getStyle(startParent) || domUtils.getComputedStyle(startParent, 'list-style-type') || (command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc');
- if (startParent.tagName.toLowerCase() == tag && nodeStyle == style) {
- for (var i = 0, ci, tmpFrag = me.document.createDocumentFragment(); ci = frag.childNodes[i++];) {
- if(domUtils.isTagNode(ci,'ol ul')){
- utils.each(domUtils.getElementsByTagName(ci,'li'),function(li){
- while(li.firstChild){
- tmpFrag.appendChild(li.firstChild);
- }
- });
- }else{
- while (ci.firstChild) {
- tmpFrag.appendChild(ci.firstChild);
- }
- }
- }
- tmp.parentNode.insertBefore(tmpFrag, tmp);
- } else {
- list = me.document.createElement(tag);
- setListStyle(list,style);
- list.appendChild(frag);
- tmp.parentNode.insertBefore(list, tmp);
- }
- domUtils.remove(tmp);
- list && adjustList(list, tag, style);
- range.moveToBookmark(bko).select();
- return;
- }
- //开始
- if (start) {
- while (start) {
- tmp = start.nextSibling;
- if (domUtils.isTagNode(start, 'ol ul')) {
- frag.appendChild(start);
- } else {
- var tmpfrag = me.document.createDocumentFragment(),
- hasBlock = 0;
- while (start.firstChild) {
- if (domUtils.isBlockElm(start.firstChild)) {
- hasBlock = 1;
- }
- tmpfrag.appendChild(start.firstChild);
- }
- if (!hasBlock) {
- var tmpP = me.document.createElement('p');
- tmpP.appendChild(tmpfrag);
- frag.appendChild(tmpP);
- } else {
- frag.appendChild(tmpfrag);
- }
- domUtils.remove(start);
- }
- start = tmp;
- }
- startParent.parentNode.insertBefore(frag, startParent.nextSibling);
- if (domUtils.isEmptyNode(startParent)) {
- range.setStartBefore(startParent);
- domUtils.remove(startParent);
- } else {
- range.setStartAfter(startParent);
- }
- modifyStart = 1;
- }
- if (end && domUtils.inDoc(endParent, me.document)) {
- //结束
- start = endParent.firstChild;
- while (start && start !== end) {
- tmp = start.nextSibling;
- if (domUtils.isTagNode(start, 'ol ul')) {
- frag.appendChild(start);
- } else {
- tmpfrag = me.document.createDocumentFragment();
- hasBlock = 0;
- while (start.firstChild) {
- if (domUtils.isBlockElm(start.firstChild)) {
- hasBlock = 1;
- }
- tmpfrag.appendChild(start.firstChild);
- }
- if (!hasBlock) {
- tmpP = me.document.createElement('p');
- tmpP.appendChild(tmpfrag);
- frag.appendChild(tmpP);
- } else {
- frag.appendChild(tmpfrag);
- }
- domUtils.remove(start);
- }
- start = tmp;
- }
- var tmpDiv = domUtils.createElement(me.document, 'div', {
- 'tmpDiv':1
- });
- domUtils.moveChild(end, tmpDiv);
- frag.appendChild(tmpDiv);
- domUtils.remove(end);
- endParent.parentNode.insertBefore(frag, endParent);
- range.setEndBefore(endParent);
- if (domUtils.isEmptyNode(endParent)) {
- domUtils.remove(endParent);
- }
- modifyEnd = 1;
- }
- }
- if (!modifyStart) {
- range.setStartBefore(me.document.getElementById(bko.start));
- }
- if (bko.end && !modifyEnd) {
- range.setEndAfter(me.document.getElementById(bko.end));
- }
- range.enlarge(true, function (node) {
- return notExchange[node.tagName];
- });
- frag = me.document.createDocumentFragment();
- var bk = range.createBookmark(),
- current = domUtils.getNextDomNode(bk.start, false, filterFn),
- tmpRange = range.cloneRange(),
- tmpNode,
- block = domUtils.isBlockElm;
- while (current && current !== bk.end && (domUtils.getPosition(current, bk.end) & domUtils.POSITION_PRECEDING)) {
- if (current.nodeType == 3 || dtd.li[current.tagName]) {
- if (current.nodeType == 1 && dtd.$list[current.tagName]) {
- while (current.firstChild) {
- frag.appendChild(current.firstChild);
- }
- tmpNode = domUtils.getNextDomNode(current, false, filterFn);
- domUtils.remove(current);
- current = tmpNode;
- continue;
- }
- tmpNode = current;
- tmpRange.setStartBefore(current);
- while (current && current !== bk.end && (!block(current) || domUtils.isBookmarkNode(current) )) {
- tmpNode = current;
- current = domUtils.getNextDomNode(current, false, null, function (node) {
- return !notExchange[node.tagName];
- });
- }
- if (current && block(current)) {
- tmp = domUtils.getNextDomNode(tmpNode, false, filterFn);
- if (tmp && domUtils.isBookmarkNode(tmp)) {
- current = domUtils.getNextDomNode(tmp, false, filterFn);
- tmpNode = tmp;
- }
- }
- tmpRange.setEndAfter(tmpNode);
- current = domUtils.getNextDomNode(tmpNode, false, filterFn);
- var li = range.document.createElement('li');
- li.appendChild(tmpRange.extractContents());
- if(domUtils.isEmptyNode(li)){
- var tmpNode = range.document.createElement('p');
- while(li.firstChild){
- tmpNode.appendChild(li.firstChild)
- }
- li.appendChild(tmpNode);
- }
- frag.appendChild(li);
- } else {
- current = domUtils.getNextDomNode(current, true, filterFn);
- }
- }
- range.moveToBookmark(bk).collapse(true);
- list = me.document.createElement(tag);
- setListStyle(list,style);
- list.appendChild(frag);
- range.insertNode(list);
- //当前list上下看能否合并
- adjustList(list, tag, style,true);
- //去掉冗余的tmpDiv
- for (var i = 0, ci, tmpDivs = domUtils.getElementsByTagName(list, 'div'); ci = tmpDivs[i++];) {
- if (ci.getAttribute('tmpDiv')) {
- domUtils.remove(ci, true)
- }
- }
- range.moveToBookmark(bko).select();
- },
- queryCommandState:function (command) {
- return domUtils.filterNodeList(this.selection.getStartElementPath(), command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul') ? 1 : 0;
- },
- queryCommandValue:function (command) {
- var node = domUtils.filterNodeList(this.selection.getStartElementPath(), command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul');
- return node ? getStyle(node) || domUtils.getComputedStyle(node, 'list-style-type') : null;
- }
- };
- };
- ///import core
- ///import plugins/serialize.js
- ///import plugins/undo.js
- ///commands 查看源码
- ///commandsName Source
- ///commandsTitle 查看源码
- (function (){
- function SourceFormater(config){
- config = config || {};
- this.indentChar = config.indentChar || ' ';
- this.breakChar = config.breakChar || '\n';
- this.selfClosingEnd = config.selfClosingEnd || ' />';
- }
- var unhtml1 = function (){
- var map = { '<': '<', '>': '>', '"': '"', "'": ''' };
- function rep( m ){ return map[m]; }
- return function ( str ) {
- str = str + '';
- return str ? str.replace( /[<>"']/g, rep ) : '';
- };
- }();
- var inline = utils.extend({a:1,A:1},dtd.$inline,true);
- function printAttrs(attrs){
- var buff = [];
- for (var k in attrs) {
- buff.push(k + '="' + unhtml1(attrs[k]) + '"');
- }
- return buff.join(' ');
- }
- SourceFormater.prototype = {
- format: function (html){
- var node = UE.serialize.parseHTML(html);
- this.buff = [];
- this.indents = '';
- this.indenting = 1;
- this.visitNode(node);
- return this.buff.join('');
- },
- visitNode: function (node){
- if (node.type == 'fragment') {
- this.visitChildren(node.children);
- } else if (node.type == 'element') {
- var selfClosing = dtd.$empty[node.tag];
- this.visitTag(node.tag, node.attributes, selfClosing);
- this.visitChildren(node.children);
- if (!selfClosing) {
- this.visitEndTag(node.tag);
- }
- } else if (node.type == 'comment') {
- this.visitComment(node.data);
- } else {
- this.visitText(node.data,dtd.$notTransContent[node.parent.tag]);
- }
- },
- visitChildren: function (children){
- for (var i=0; i<children.length; i++) {
- this.visitNode(children[i]);
- }
- },
- visitTag: function (tag, attrs, selfClosing){
- if (this.indenting) {
- this.indent();
- } else if (!inline[tag]) { // todo: 去掉a, 因为dtd的inline里面没有a
- this.newline();
- this.indent();
- }
- this.buff.push('<', tag);
- var attrPart = printAttrs(attrs);
- if (attrPart) {
- this.buff.push(' ', attrPart);
- }
- if (selfClosing) {
- this.buff.push(this.selfClosingEnd);
- if (tag == 'br') {
- this.newline();
- }
- } else {
- this.buff.push('>');
- this.indents += this.indentChar;
- }
- if (!inline[tag]) {
- this.newline();
- }
- },
- indent: function (){
- this.buff.push(this.indents);
- this.indenting = 0;
- },
- newline: function (){
- this.buff.push(this.breakChar);
- this.indenting = 1;
- },
- visitEndTag: function (tag){
-
- this.indents = this.indents.slice(0, -this.indentChar.length);
- if (this.indenting) {
- this.indent();
- } else if (!inline[tag]) {
- this.newline();
- this.indent();
- }
- this.buff.push('</', tag, '>');
- },
- visitText: function (text,notTrans){
- if (this.indenting) {
- this.indent();
- }
-
- // if(!notTrans){
- // text = text.replace(/ /g, ' ').replace(/[ ][ ]+/g, function (m){
- // return new Array(m.length + 1).join(' ');
- // }).replace(/(?:^ )|(?: $)/g, ' ');
- // }
- text = text.replace(/ /g, ' ');
- this.buff.push(text);
- },
- visitComment: function (text){
- if (this.indenting) {
- this.indent();
- }
- this.buff.push('<!--', text, '-->');
- }
- };
- var sourceEditors = {
- textarea: function (editor, holder){
- var textarea = holder.ownerDocument.createElement('textarea');
- textarea.style.cssText = 'position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;';
- // todo: IE下只有onresize属性可用... 很纠结
- if (browser.ie && browser.version < 8) {
- textarea.style.width = holder.offsetWidth + 'px';
- textarea.style.height = holder.offsetHeight + 'px';
- holder.onresize = function (){
- textarea.style.width = holder.offsetWidth + 'px';
- textarea.style.height = holder.offsetHeight + 'px';
- };
- }
- holder.appendChild(textarea);
- return {
- setContent: function (content){
- textarea.value = content;
- },
- getContent: function (){
- return textarea.value;
- },
- select: function (){
- var range;
- if (browser.ie) {
- range = textarea.createTextRange();
- range.collapse(true);
- range.select();
- } else {
- //todo: chrome下无法设置焦点
- textarea.setSelectionRange(0, 0);
- textarea.focus();
- }
- },
- dispose: function (){
- holder.removeChild(textarea);
- // todo
- holder.onresize = null;
- textarea = null;
- holder = null;
- }
- };
- },
- codemirror: function (editor, holder){
- var codeEditor = window.CodeMirror(holder, {
- mode: "text/html",
- tabMode: "indent",
- lineNumbers: true,
- lineWrapping:true
- });
- var dom = codeEditor.getWrapperElement();
- dom.style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;';
- codeEditor.getScrollerElement().style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;';
- codeEditor.refresh();
- return {
- getCodeMirror:function(){
- return codeEditor;
- },
- setContent: function (content){
- codeEditor.setValue(content);
- },
- getContent: function (){
- return codeEditor.getValue();
- },
- select: function (){
- codeEditor.focus();
- },
- dispose: function (){
- holder.removeChild(dom);
- dom = null;
- codeEditor = null;
- }
- };
- }
- };
- UE.plugins['source'] = function (){
- var me = this;
- var opt = this.options;
- var formatter = new SourceFormater(opt.source);
- var sourceMode = false;
- var sourceEditor;
- opt.sourceEditor = browser.ie ? 'textarea' : (opt.sourceEditor || 'codemirror');
- me.setOpt({
- sourceEditorFirst:false
- });
- function createSourceEditor(holder){
- return sourceEditors[opt.sourceEditor == 'codemirror' && window.CodeMirror ? 'codemirror' : 'textarea'](me, holder);
- }
- var bakCssText;
- //解决在源码模式下getContent不能得到最新的内容问题
- var oldGetContent = me.getContent,
- bakAddress;
- me.commands['source'] = {
- execCommand: function (){
- sourceMode = !sourceMode;
- if (sourceMode) {
- bakAddress = me.selection.getRange().createAddress(false,true);
- me.undoManger && me.undoManger.save(true);
- if(browser.gecko){
- me.body.contentEditable = false;
- }
- bakCssText = me.iframe.style.cssText;
- me.iframe.style.cssText += 'position:absolute;left:-32768px;top:-32768px;';
- var content = formatter.format(me.hasContents() ? me.getContent() : '');
- sourceEditor = createSourceEditor(me.iframe.parentNode);
- sourceEditor.setContent(content);
- setTimeout(function (){
- sourceEditor.select();
- me.addListener('fullscreenchanged', function(){
- try{
- sourceEditor.getCodeMirror().refresh()
- }catch(e){}
- });
- });
- //重置getContent,源码模式下取值也能是最新的数据
- me.getContent = function (){
- var cont = sourceEditor.getContent() || '<p>' + (browser.ie ? '' : '<br/>')+'</p>';
- return cont.replace(/>[\n\r\t]+([ ]{4})+/g,'>').replace(/[\n\r\t]+([ ]{4})+</g,'<').replace(/>[\n\r\t]+</g,'><');
- };
- } else {
- me.iframe.style.cssText = bakCssText;
- var cont = sourceEditor.getContent() || '<p>' + (browser.ie ? '' : '<br/>')+'</p>';
- cont = cont.replace(/>[\n\r\t]+([ ]{4})+/g,'>').replace(/[\n\r\t]+([ ]{4})+</g,'<').replace(/>[\n\r\t]+</g,'><');
- me.setContent(cont);
- sourceEditor.dispose();
- sourceEditor = null;
- //还原getContent方法
- me.getContent = oldGetContent;
- var first = me.body.firstChild;
- //trace:1106 都删除空了,下边会报错,所以补充一个p占位
- if(!first){
- me.body.innerHTML = '<p>'+(browser.ie?'':'<br/>')+'</p>';
- first = me.body.firstChild;
- }
- //要在ifm为显示时ff才能取到selection,否则报错
- //这里不能比较位置了
- me.undoManger && me.undoManger.save(true);
- if(browser.gecko){
- var input = document.createElement('input');
- input.style.cssText = 'position:absolute;left:0;top:-32768px';
- document.body.appendChild(input);
- me.body.contentEditable = false;
- setTimeout(function(){
- domUtils.setViewportOffset(input, { left: -32768, top: 0 });
- input.focus();
- setTimeout(function(){
- me.body.contentEditable = true;
- me.selection.getRange().moveToAddress(bakAddress).select();
- domUtils.remove(input);
- });
- });
- }else{
- //ie下有可能报错,比如在代码顶头的情况
- try{
- me.selection.getRange().moveToAddress(bakAddress).select();
- }catch(e){}
- }
- }
- this.fireEvent('sourcemodechanged', sourceMode);
- },
- queryCommandState: function (){
- return sourceMode|0;
- },
- notNeedUndo : 1
- };
- var oldQueryCommandState = me.queryCommandState;
- me.queryCommandState = function (cmdName){
- cmdName = cmdName.toLowerCase();
- if (sourceMode) {
- //源码模式下可以开启的命令
- return cmdName in {
- 'source' : 1,
- 'fullscreen' : 1
- } ? 1 : -1
- }
- return oldQueryCommandState.apply(this, arguments);
- };
- if(opt.sourceEditor == "codemirror"){
- me.addListener("ready",function(){
- utils.loadFile(document,{
- src : opt.codeMirrorJsUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.js",
- tag : "script",
- type : "text/javascript",
- defer : "defer"
- },function(){
- if(opt.sourceEditorFirst){
- setTimeout(function(){
- me.execCommand("source");
- },0);
- }
- });
- utils.loadFile(document,{
- tag : "link",
- rel : "stylesheet",
- type : "text/css",
- href : opt.codeMirrorCssUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.css"
- });
- });
- }
- };
- })();
- ///import core
- ///import plugins/undo.js
- ///commands 设置回车标签p或br
- ///commandsName EnterKey
- ///commandsTitle 设置回车标签p或br
- /**
- * @description 处理回车
- * @author zhanyi
- */
- UE.plugins['enterkey'] = function() {
- var hTag,
- me = this,
- tag = me.options.enterTag;
- me.addListener('keyup', function(type, evt) {
- var keyCode = evt.keyCode || evt.which;
- if (keyCode == 13) {
- var range = me.selection.getRange(),
- start = range.startContainer,
- doSave;
- //修正在h1-h6里边回车后不能嵌套p的问题
- if (!browser.ie) {
- if (/h\d/i.test(hTag)) {
- if (browser.gecko) {
- var h = domUtils.findParentByTagName(start, [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption','table'], true);
- if (!h) {
- me.document.execCommand('formatBlock', false, '<p>');
- doSave = 1;
- }
- } else {
- //chrome remove div
- if (start.nodeType == 1) {
- var tmp = me.document.createTextNode(''),div;
- range.insertNode(tmp);
- div = domUtils.findParentByTagName(tmp, 'div', true);
- if (div) {
- var p = me.document.createElement('p');
- while (div.firstChild) {
- p.appendChild(div.firstChild);
- }
- div.parentNode.insertBefore(p, div);
- domUtils.remove(div);
- range.setStartBefore(tmp).setCursor();
- doSave = 1;
- }
- domUtils.remove(tmp);
- }
- }
- if (me.undoManger && doSave) {
- me.undoManger.save();
- }
- }
- //没有站位符,会出现多行的问题
- browser.opera && range.select();
- }
- // if(browser.ie){
- // range = me.selection.getRange();
- // start = range.startContainer;
- // while(start){
- // if(start.nodeType == 1 && start.tagName == 'P'){
- // break;
- // }
- // start = start.parentNode;
- // }
- // if(start && domUtils.isEmptyBlock(start)){
- // start.innerHTML = ' ';
- // var rng = me.selection.getRange();
- // rng.setStart(start,0).setCursor(false,true);
- // }
- // }
- setTimeout(function() {
- me.selection.getRange().scrollToView(me.autoHeightEnabled, me.autoHeightEnabled ? domUtils.getXY(me.iframe).y : 0);
- }, 50);
- }
- });
- me.addListener('keydown', function(type, evt) {
- var keyCode = evt.keyCode || evt.which;
- if (keyCode == 13) {//回车
- if (me.undoManger) {
- me.undoManger.save();
- }
- hTag = '';
- var range = me.selection.getRange();
- if (!range.collapsed) {
- //跨td不能删
- var start = range.startContainer,
- end = range.endContainer,
- startTd = domUtils.findParentByTagName(start, 'td', true),
- endTd = domUtils.findParentByTagName(end, 'td', true);
- if (startTd && endTd && startTd !== endTd || !startTd && endTd || startTd && !endTd) {
- evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false);
- return;
- }
- }
- if (tag == 'p') {
- if (!browser.ie) {
- start = domUtils.findParentByTagName(range.startContainer, ['ol','ul','p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption'], true);
- //opera下执行formatblock会在table的场景下有问题,回车在opera原生支持很好,所以暂时在opera去掉调用这个原生的command
- //trace:2431
- if (!start && !browser.opera) {
- me.document.execCommand('formatBlock', false, '<p>');
- if (browser.gecko) {
- range = me.selection.getRange();
- start = domUtils.findParentByTagName(range.startContainer, 'p', true);
- start && domUtils.removeDirtyAttr(start);
- }
- } else {
- hTag = start.tagName;
- start.tagName.toLowerCase() == 'p' && browser.gecko && domUtils.removeDirtyAttr(start);
- }
- }
- } else {
- evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false);
- if (!range.collapsed) {
- range.deleteContents();
- start = range.startContainer;
- if (start.nodeType == 1 && (start = start.childNodes[range.startOffset])) {
- while (start.nodeType == 1) {
- if (dtd.$empty[start.tagName]) {
- range.setStartBefore(start).setCursor();
- if (me.undoManger) {
- me.undoManger.save();
- }
- return false;
- }
- if (!start.firstChild) {
- var br = range.document.createElement('br');
- start.appendChild(br);
- range.setStart(start, 0).setCursor();
- if (me.undoManger) {
- me.undoManger.save();
- }
- return false;
- }
- start = start.firstChild;
- }
- if (start === range.startContainer.childNodes[range.startOffset]) {
- br = range.document.createElement('br');
- range.insertNode(br).setCursor();
- } else {
- range.setStart(start, 0).setCursor();
- }
- } else {
- br = range.document.createElement('br');
- range.insertNode(br).setStartAfter(br).setCursor();
- }
- } else {
- br = range.document.createElement('br');
- range.insertNode(br);
- var parent = br.parentNode;
- if (parent.lastChild === br) {
- br.parentNode.insertBefore(br.cloneNode(true), br);
- range.setStartBefore(br);
- } else {
- range.setStartAfter(br);
- }
- range.setCursor();
- }
- }
- }
- });
- };
- /*
- * 处理特殊键的兼容性问题
- */
- UE.plugins['keystrokes'] = function() {
- var me = this;
- me.addListener('keydown', function(type, evt) {
- var keyCode = evt.keyCode || evt.which,
- rng = me.selection.getRange();
- //处理全选的情况
- if(!rng.collapsed && !(evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey || keyCode == 9 )){
- var tmpNode = rng.startContainer;
- if(domUtils.isFillChar(tmpNode)){
- rng.setStartBefore(tmpNode)
- }
- tmpNode = rng.endContainer;
- if(domUtils.isFillChar(tmpNode)){
- rng.setEndAfter(tmpNode)
- }
- rng.txtToElmBoundary();
- //结束边界可能放到了br的前边,要把br包含进来
- // x[xxx]<br/>
- if(rng.endContainer && rng.endContainer.nodeType == 1){
- tmpNode = rng.endContainer.childNodes[rng.endOffset];
- if(tmpNode && domUtils.isBr(tmpNode)){
- rng.setEndAfter(tmpNode);
- }
- }
- if(rng.startOffset == 0){
- tmpNode = rng.startContainer;
- if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){
- tmpNode = rng.endContainer;
- if(rng.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){
- me.fireEvent('saveScene');
- me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';
- rng.setStart(me.body.firstChild,0).setCursor(false,true);
- browser.ie && me._selectionChange();
- domUtils.preventDefault(evt);
- return;
- }
- }
- }
- }
- //处理backspace/del
- if (keyCode == 8) {//|| keyCode == 46
- var start,end;
- //避免按两次删除才能生效的问题
- if(rng.inFillChar()){
- start = rng.startContainer;
- rng.setStartBefore(start).shrinkBoundary(true).collapse(true);
- if(domUtils.isFillChar(start)){
- domUtils.remove(start)
- }else{
- start.nodeValue = start.nodeValue.replace(new RegExp('^' + domUtils.fillChar ),'');
- }
- }
- //解决选中control元素不能删除的问题
- if (start = rng.getClosedNode()) {
- me.fireEvent('saveScene');
- rng.setStartBefore(start);
- domUtils.remove(start);
- rng.setCursor();
- me.fireEvent('saveScene');
- domUtils.preventDefault(evt);
- return;
- }
- //阻止在table上的删除
- if (!browser.ie) {
- start = domUtils.findParentByTagName(rng.startContainer, 'table', true);
- end = domUtils.findParentByTagName(rng.endContainer, 'table', true);
- if (start && !end || !start && end || start !== end) {
- evt.preventDefault();
- return;
- }
- }
- }
- //处理tab键的逻辑
- if (keyCode == 9) {
- //不处理以下标签
- var excludeTagNameForTabKey = {
- 'ol' : 1,
- 'ul' : 1,
- 'table':1
- };
- //处理组件里的tab按下事件
- if(me.fireEvent('tabkeydown')){
- domUtils.preventDefault(evt);
- return;
- }
- range = me.selection.getRange();
- me.fireEvent('saveScene');
- for (var i = 0,txt = '',tabSize = me.options.tabSize|| 4,tabNode = me.options.tabNode || ' '; i < tabSize; i++) {
- txt += tabNode;
- }
- var span = me.document.createElement('span');
- span.innerHTML = txt + domUtils.fillChar;
- if (range.collapsed) {
- range.insertNode(span.cloneNode(true).firstChild).setCursor(true);
- } else {
- //普通的情况
- start = domUtils.findParent(range.startContainer, filterFn);
- end = domUtils.findParent(range.endContainer, filterFn);
- if (start && end && start === end) {
- range.deleteContents();
- range.insertNode(span.cloneNode(true).firstChild).setCursor(true);
- } else {
- var bookmark = range.createBookmark(),
- filterFn = function(node) {
- return domUtils.isBlockElm(node) && !excludeTagNameForTabKey[node.tagName.toLowerCase()]
- };
- range.enlarge(true);
- var bookmark2 = range.createBookmark(),
- current = domUtils.getNextDomNode(bookmark2.start, false, filterFn);
- while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) {
- current.insertBefore(span.cloneNode(true).firstChild, current.firstChild);
- current = domUtils.getNextDomNode(current, false, filterFn);
- }
- range.moveToBookmark(bookmark2).moveToBookmark(bookmark).select();
- }
- }
- domUtils.preventDefault(evt)
- }
- //trace:1634
- //ff的del键在容器空的时候,也会删除
- if(browser.gecko && keyCode == 46){
- range = me.selection.getRange();
- if(range.collapsed){
- start = range.startContainer;
- if(domUtils.isEmptyBlock(start)){
- var parent = start.parentNode;
- while(domUtils.getChildCount(parent) == 1 && !domUtils.isBody(parent)){
- start = parent;
- parent = parent.parentNode;
- }
- if(start === parent.lastChild)
- evt.preventDefault();
- return;
- }
- }
- }
- });
- me.addListener('keyup', function(type, evt) {
- var keyCode = evt.keyCode || evt.which,
- rng;
- if(keyCode == 8){
- rng = me.selection.getRange();
- //处理当删除到body时,要重新给p标签展位
- if(rng.collapsed && domUtils.isBody(rng.startContainer)){
- var tmpNode = domUtils.createElement(me.document,'p',{
- 'innerHTML' : browser.ie ? domUtils.fillChar : '<br/>'
- });
- rng.insertNode(tmpNode).setStart(tmpNode,0).setCursor(false,true);
- }
- // //chrome下如果删除了inline标签,浏览器会有记忆,在输入文字还是会套上刚才删除的标签,所以这里再选一次就不会了
- if(browser.chrome && rng.collapsed && rng.startContainer.nodeType == 1 && domUtils.isEmptyBlock(rng.startContainer)){
- rng.select(true);
- }
- }
- })
- };
- ///import core
- ///commands 修复chrome下图片不能点击的问题
- ///commandsName FixImgClick
- ///commandsTitle 修复chrome下图片不能点击的问题
- //修复chrome下图片不能点击的问题
- //todo 可以改大小
- UE.plugins['fiximgclick'] = function() {
- var me = this;
- if ( browser.webkit ) {
- me.addListener( 'click', function( type, e ) {
- if ( e.target.tagName == 'IMG' ) {
- var range = new dom.Range( me.document );
- range.selectNode( e.target ).select();
- }
- } );
- }
- };
- ///import core
- ///commands 为非ie浏览器自动添加a标签
- ///commandsName AutoLink
- ///commandsTitle 自动增加链接
- /**
- * @description 为非ie浏览器自动添加a标签
- * @author zhanyi
- */
- UE.plugins['autolink'] = function() {
- var cont = 0;
- if (browser.ie) {
- return;
- }
- var me = this;
- me.addListener('reset',function(){
- cont = 0;
- });
- me.addListener('keydown', function(type, evt) {
- var keyCode = evt.keyCode || evt.which;
- if (keyCode == 32 || keyCode == 13) {
- var sel = me.selection.getNative(),
- range = sel.getRangeAt(0).cloneRange(),
- offset,
- charCode;
- var start = range.startContainer;
- while (start.nodeType == 1 && range.startOffset > 0) {
- start = range.startContainer.childNodes[range.startOffset - 1];
- if (!start){
- break;
- }
- range.setStart(start, start.nodeType == 1 ? start.childNodes.length : start.nodeValue.length);
- range.collapse(true);
- start = range.startContainer;
- }
- do{
- if (range.startOffset == 0) {
- start = range.startContainer.previousSibling;
- while (start && start.nodeType == 1) {
- start = start.lastChild;
- }
- if (!start || domUtils.isFillChar(start)){
- break;
- }
- offset = start.nodeValue.length;
- } else {
- start = range.startContainer;
- offset = range.startOffset;
- }
- range.setStart(start, offset - 1);
- charCode = range.toString().charCodeAt(0);
- } while (charCode != 160 && charCode != 32);
- if (range.toString().replace(new RegExp(domUtils.fillChar, 'g'), '').match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i)) {
- while(range.toString().length){
- if(/^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test(range.toString())){
- break;
- }
- try{
- range.setStart(range.startContainer,range.startOffset+1);
- }catch(e){
- //trace:2121
- var start = range.startContainer;
- while(!(next = start.nextSibling)){
- if(domUtils.isBody(start)){
- return;
- }
- start = start.parentNode;
- }
- range.setStart(next,0);
- }
- }
- //range的开始边界已经在a标签里的不再处理
- if(domUtils.findParentByTagName(range.startContainer,'a',true)){
- return;
- }
- var a = me.document.createElement('a'),text = me.document.createTextNode(' '),href;
- me.undoManger && me.undoManger.save();
- a.appendChild(range.extractContents());
- a.href = a.innerHTML = a.innerHTML.replace(/<[^>]+>/g,'');
- href = a.getAttribute("href").replace(new RegExp(domUtils.fillChar,'g'),'');
- href = /^(?:https?:\/\/)/ig.test(href) ? href : "http://"+ href;
- a.setAttribute('data_ue_src',utils.html(href));
- a.href = utils.html(href);
- range.insertNode(a);
- a.parentNode.insertBefore(text, a.nextSibling);
- range.setStart(text, 0);
- range.collapse(true);
- sel.removeAllRanges();
- sel.addRange(range);
- me.undoManger && me.undoManger.save();
- }
- }
- });
- };
- ///import core
- ///commands 当输入内容超过编辑器高度时,编辑器自动增高
- ///commandsName AutoHeight,autoHeightEnabled
- ///commandsTitle 自动增高
- /**
- * @description 自动伸展
- * @author zhanyi
- */
- UE.plugins['autoheight'] = function () {
- var me = this;
- //提供开关,就算加载也可以关闭
- me.autoHeightEnabled = me.options.autoHeightEnabled !== false;
- if (!me.autoHeightEnabled) {
- return;
- }
- var bakOverflow,
- span, tmpNode,
- lastHeight = 0,
- options = me.options,
- currentHeight,
- timer;
- function adjustHeight() {
- var me = this;
- clearTimeout(timer);
- if(isFullscreen)return;
- timer = setTimeout(function () {
- if (me.queryCommandState && me.queryCommandState('source') != 1) {
- if (!span) {
- span = me.document.createElement('span');
- //trace:1764
- span.style.cssText = 'display:block;width:0;margin:0;padding:0;border:0;clear:both;';
- span.innerHTML = '.';
- }
- tmpNode = span.cloneNode(true);
- me.body.appendChild(tmpNode);
- currentHeight = Math.max(domUtils.getXY(tmpNode).y + tmpNode.offsetHeight,Math.max(options.minFrameHeight, options.initialFrameHeight));
- if (currentHeight != lastHeight) {
- me.setHeight(currentHeight);
- lastHeight = currentHeight;
- }
- domUtils.remove(tmpNode);
- }
- }, 50);
- }
- var isFullscreen;
- me.addListener('fullscreenchanged',function(cmd,f){
- isFullscreen = f
- });
- me.addListener('destroy', function () {
- me.removeListener('contentchange', adjustHeight);
- me.removeListener('afterinserthtml',adjustHeight);
- me.removeListener('keyup', adjustHeight);
- me.removeListener('mouseup', adjustHeight);
- });
- me.enableAutoHeight = function () {
- if (!me.autoHeightEnabled) {
- return;
- }
- var doc = me.document;
- me.autoHeightEnabled = true;
- bakOverflow = doc.body.style.overflowY;
- doc.body.style.overflowY = 'hidden';
- me.addListener('contentchange', adjustHeight);
- me.addListener('afterinserthtml',adjustHeight)
- me.addListener('keyup', adjustHeight);
- me.addListener('mouseup', adjustHeight);
- //ff不给事件算得不对
- setTimeout(function () {
- adjustHeight.call(this);
- }, browser.gecko ? 100 : 0);
- me.fireEvent('autoheightchanged', me.autoHeightEnabled);
- };
- me.disableAutoHeight = function () {
- me.body.style.overflowY = bakOverflow || '';
- me.removeListener('contentchange', adjustHeight);
- me.removeListener('keyup', adjustHeight);
- me.removeListener('mouseup', adjustHeight);
- me.autoHeightEnabled = false;
- me.fireEvent('autoheightchanged', me.autoHeightEnabled);
- };
- me.addListener('ready', function () {
- me.enableAutoHeight();
- //trace:1764
- var timer;
- domUtils.on(browser.ie ? me.body : me.document, browser.webkit ? 'dragover' : 'drop', function () {
- clearTimeout(timer);
- timer = setTimeout(function () {
- adjustHeight.call(this);
- }, 100);
- });
- });
- };
- ///import core
- ///commands 悬浮工具栏
- ///commandsName AutoFloat,autoFloatEnabled
- ///commandsTitle 悬浮工具栏
- /*
- * modified by chengchao01
- *
- * 注意: 引入此功能后,在IE6下会将body的背景图片覆盖掉!
- */
- UE.plugins['autofloat'] = function() {
- var me = this,
- lang = me.getLang();
- me.setOpt({
- topOffset:0
- });
- var optsAutoFloatEnabled = me.options.autoFloatEnabled !== false,
- topOffset = me.options.topOffset;
- //如果不固定toolbar的位置,则直接退出
- if(!optsAutoFloatEnabled){
- return;
- }
- var uiUtils = UE.ui.uiUtils,
- LteIE6 = browser.ie && browser.version <= 6,
- quirks = browser.quirks;
- function checkHasUI(editor){
- if(!editor.ui){
- alert(lang.autofloatMsg);
- return 0;
- }
- return 1;
- }
- function fixIE6FixedPos(){
- var docStyle = document.body.style;
- docStyle.backgroundImage = 'url("about:blank")';
- docStyle.backgroundAttachment = 'fixed';
- }
- var bakCssText,
- placeHolder = document.createElement('div'),
- toolbarBox,orgTop,
- getPosition,
- flag =true; //ie7模式下需要偏移
- function setFloating(){
- var toobarBoxPos = domUtils.getXY(toolbarBox),
- origalFloat = domUtils.getComputedStyle(toolbarBox,'position'),
- origalLeft = domUtils.getComputedStyle(toolbarBox,'left');
- toolbarBox.style.width = toolbarBox.offsetWidth + 'px';
- toolbarBox.style.zIndex = me.options.zIndex * 1 + 1;
- toolbarBox.parentNode.insertBefore(placeHolder, toolbarBox);
- if (LteIE6 || (quirks && browser.ie)) {
- if(toolbarBox.style.position != 'absolute'){
- toolbarBox.style.position = 'absolute';
- }
- toolbarBox.style.top = (document.body.scrollTop||document.documentElement.scrollTop) - orgTop + topOffset + 'px';
- } else {
- if (browser.ie7Compat && flag) {
- flag = false;
- toolbarBox.style.left = domUtils.getXY(toolbarBox).x - document.documentElement.getBoundingClientRect().left+2 + 'px';
- }
- if(toolbarBox.style.position != 'fixed'){
- toolbarBox.style.position = 'fixed';
- toolbarBox.style.top = topOffset +"px";
- ((origalFloat == 'absolute' || origalFloat == 'relative') && parseFloat(origalLeft)) && (toolbarBox.style.left = toobarBoxPos.x + 'px');
- }
- }
- }
- function unsetFloating(){
- flag = true;
- if(placeHolder.parentNode){
- placeHolder.parentNode.removeChild(placeHolder);
- }
- toolbarBox.style.cssText = bakCssText;
- }
- function updateFloating(){
- var rect3 = getPosition(me.container);
- if (rect3.top < 0 && rect3.bottom - toolbarBox.offsetHeight > 0) {
- setFloating();
- }else{
- unsetFloating();
- }
- }
- var defer_updateFloating = utils.defer(function(){
- updateFloating();
- },browser.ie ? 200 : 100,true);
- me.addListener('destroy',function(){
- domUtils.un(window, ['scroll','resize'], updateFloating);
- me.removeListener('keydown', defer_updateFloating);
- });
- me.addListener('ready', function(){
- if(checkHasUI(me)){
- getPosition = uiUtils.getClientRect;
- toolbarBox = me.ui.getDom('toolbarbox');
- orgTop = getPosition(toolbarBox).top;
- bakCssText = toolbarBox.style.cssText;
- placeHolder.style.height = toolbarBox.offsetHeight + 'px';
- if(LteIE6){
- fixIE6FixedPos();
- }
- domUtils.on(window, ['scroll','resize'], updateFloating);
- me.addListener('keydown', defer_updateFloating);
- me.addListener('beforefullscreenchange', function (t, enabled){
- if (enabled) {
- unsetFloating();
- }
- });
- me.addListener('fullscreenchanged', function (t, enabled){
- if (!enabled) {
- updateFloating();
- }
- });
- me.addListener('sourcemodechanged', function (t, enabled){
- setTimeout(function (){
- updateFloating();
- },0);
- });
- me.addListener("clearDoc",function(){
- setTimeout(function(){
- updateFloating();
- },0);
- })
- }
- });
- };
- ///import core
- ///import plugins/inserthtml.js
- ///commands 插入代码
- ///commandsName HighlightCode
- ///commandsTitle 插入代码
- ///commandsDialog dialogs\highlightcode
- UE.plugins['highlightcode'] = function() {
- var me = this;
- if(!/highlightcode/i.test(me.options.toolbars.join(''))){
- return;
- }
- me.commands['highlightcode'] = {
- execCommand: function (cmdName, code, syntax) {
- var range = this.selection.getRange(),
- start = domUtils.findParentByTagName(range.startContainer, 'table', true),
- end = domUtils.findParentByTagName(range.endContainer, 'table', true);
- if(start && end && start === end && domUtils.hasClass(start,'syntaxhighlighter')){
- if(start.nextSibling){
- range.setStart(start.nextSibling,0)
- }else{
- if(start.previousSibling){
- range.setStartAtLast(start.previousSibling)
- }else{
- var p = me.document.createElement('p');
- domUtils.fillNode(me.document,p);
- start.parentNode.insertBefore(p,start);
- range.setStart(p,0)
- }
- }
- range.setCursor(false,true);
- domUtils.remove(start);
- }
- if(code && syntax){
- me.execCommand('inserthtml','<pre id="highlightcode_id" class="brush: '+syntax+';toolbar:false;">'+utils.unhtml(code)+'</pre>',true);
- var pre = me.document.getElementById('highlightcode_id');
- if(pre){
- domUtils.removeAttributes(pre,'id');
- me.window.SyntaxHighlighter.highlight(pre);
- }
- }
- },
- queryCommandState: function(){
- return queryHighlight.call(this);
- }
- };
- function queryHighlight(){
- try{
- var range = this.selection.getRange(),start,end;
- range.adjustmentBoundary();
- start = domUtils.findParent(range.startContainer,function(node){
- return node.nodeType == 1 && node.tagName == 'TABLE' && domUtils.hasClass(node,'syntaxhighlighter');
- },true);
- end = domUtils.findParent(range.endContainer,function(node){
- return node.nodeType == 1 && node.tagName == 'TABLE' && domUtils.hasClass(node,'syntaxhighlighter');
- },true);
- return start && end && start == end ? 1 : 0;
- }catch(e){
- return 0;
- }
- }
- //不需要判断highlight的command列表
- me.notNeedHighlightQuery ={
- help:1,
- undo:1,
- redo:1,
- source:1,
- print:1,
- searchreplace:1,
- fullscreen:1,
- preview:1,
- insertparagraph:1,
- elementpath:1,
- highlightcode:1
- };
- //将queyCommamndState重置
- var orgQuery = me.queryCommandState;
- me.queryCommandState = function(cmd){
- if(!me.notNeedHighlightQuery[cmd.toLowerCase()] && queryHighlight.call(this) == 1){
- return -1;
- }
- return orgQuery.apply(this,arguments)
- };
- me.addListener('beforeselectionchange afterselectionchange',function(type){
- me.highlight = /^b/.test(type) ? me.queryCommandState('highlightcode') : 0;
- });
- me.addListener("ready",function(){
- //避免重复加载高亮文件
- if(typeof me.XRegExp == "undefined"){
- utils.loadFile(me.document,{
- id : "syntaxhighlighter_js",
- src : me.options.highlightJsUrl || me.options.UEDITOR_HOME_URL + "third-party/SyntaxHighlighter/shCore.js",
- tag : "script",
- type : "text/javascript",
- defer : "defer"
- },function(){
- changePre.call(me);
- });
- }
- if(!me.document.getElementById("syntaxhighlighter_css")){
- utils.loadFile(me.document,{
- id : "syntaxhighlighter_css",
- tag : "link",
- rel : "stylesheet",
- type : "text/css",
- href : me.options.highlightCssUrl ||me.options.UEDITOR_HOME_URL + "third-party/SyntaxHighlighter/shCoreDefault.css"
- });
- }
- });
- me.addListener("beforegetcontent beforegetscene",function(){
- utils.each(domUtils.getElementsByTagName(me.body,'table','syntaxhighlighter'),function(di){
- var str = [],parentCode = '';
- utils.each(di.getElementsByTagName('code'),function(ci){
- if(parentCode !== ci.parentNode){
- parentCode = ci.parentNode;
- //去掉左右空格,针对ie的不能回退的问题
- str.push(utils.trim(parentCode[browser.ie?'innerText':'textContent']))
- }
- });
- var pre = domUtils.createElement(me.document,'pre',{
- 'class' : 'brush: '+di.className.replace(/\s+/g,' ').split(' ')[1]+';toolbar:false;'
- });
- pre.appendChild(me.document.createTextNode(str.join('\n')));
- di.parentNode.replaceChild(pre,di);
- });
- });
- me.addListener("aftergetcontent aftersetcontent aftergetscene",changePre);
- //避免table插件对于代码高亮的影响
- me.addListener('excludetable excludeNodeinautotype',function (cmd,target){
- if(target && domUtils.findParent(target,function(node){
- return domUtils.hasClass(node,'syntaxhighlighter');
- },true)){
- return true;
- }
- });
- function changePre(){
- var me = this;
- if(!me.window||!me.window.SyntaxHighlighter)return;
- utils.each(domUtils.getElementsByTagName(me.document,"pre"),function(pi){
- if(domUtils.hasClass(pi,'brush')){
- me.window.SyntaxHighlighter.highlight(pi);
- }
- });
- }
- me.addListener('getAllHtml',function(type,headHtml){
- var coreHtml = '';
- for(var i= 0,ci,divs=domUtils.getElementsByTagName(me.document,'table');ci=divs[i++];){
- if(domUtils.hasClass(ci,'syntaxhighlighter')){
- coreHtml = '<script type="text/javascript">window.onload = function(){SyntaxHighlighter.highlight();' +
- 'setTimeout(function(){ '+
- " var tables = document.getElementsByTagName('table');"+
- " for(var t= 0,ti;ti=tables[t++];){"+
- " if(/SyntaxHighlighter/i.test(ti.className)){"+
- " var tds = ti.getElementsByTagName('td');"+
- " for(var i=0,li,ri;li=tds[0].childNodes[i];i++){"+
- " ri = tds[1].firstChild.childNodes[i];"+
- " if(ri){"+
- " ri.style.height = li.style.height = ri.offsetHeight + 'px';"+
- " }"+
- " }"+
- " }"+
- " }"+
- '},100)' +
- '}</script>'
- break;
- }
- }
- if(!coreHtml){
- var tmpNode;
- if(tmpNode = me.document.getElementById('syntaxhighlighter_css')){
- domUtils.remove(tmpNode)
- }
- if(tmpNode = me.document.getElementById('syntaxhighlighter_js')){
- domUtils.remove(tmpNode)
- }
- }
- coreHtml && headHtml.push(coreHtml)
- });
- };
- ///import core
- ///commands 定制过滤规则
- ///commandsName Serialize
- ///commandsTitle 定制过滤规则
- UE.plugins['serialize'] = function () {
- var ie = browser.ie,
- version = browser.version;
- function ptToPx(value){
- return /pt/.test(value) ? value.replace( /([\d.]+)pt/g, function( str ) {
- return Math.round(parseFloat(str) * 96 / 72) + "px";
- } ) : value;
- }
- var me = this, autoClearEmptyNode = me.options.autoClearEmptyNode,
- EMPTY_TAG = dtd.$empty,
- parseHTML = function () {
- //干掉<a> 后便变得空格,保留</a> 这样的空格
- var RE_PART = /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g,
- RE_ATTR = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,
- EMPTY_ATTR = {checked:1,compact:1,declare:1,defer:1,disabled:1,ismap:1,multiple:1,nohref:1,noresize:1,noshade:1,nowrap:1,readonly:1,selected:1},
- CDATA_TAG = {script:1,style: 1},
- NEED_PARENT_TAG = {
- "li": { "$": 'ul', "ul": 1, "ol": 1 },
- "dd": { "$": "dl", "dl": 1 },
- "dt": { "$": "dl", "dl": 1 },
- "option": { "$": "select", "select": 1 },
- "td": { "$": "tr", "tr": 1 },
- "th": { "$": "tr", "tr": 1 },
- "tr": { "$": "tbody", "tbody": 1, "thead": 1, "tfoot": 1, "table": 1 },
- "tbody": { "$": "table", 'table':1,"colgroup": 1 },
- "thead": { "$": "table", "table": 1 },
- "tfoot": { "$": "table", "table": 1 },
- "col": { "$": "colgroup","colgroup":1 }
- };
- var NEED_CHILD_TAG = {
- "table": "td", "tbody": "td", "thead": "td", "tfoot": "td", //"tr": "td",
- "colgroup": "col",
- "ul": "li", "ol": "li",
- "dl": "dd",
- "select": "option"
- };
- function parse( html, callbacks ) {
- var match,
- nextIndex = 0,
- tagName,
- cdata;
- RE_PART.exec( "" );
- while ( (match = RE_PART.exec( html )) ) {
- var tagIndex = match.index;
- if ( tagIndex > nextIndex ) {
- var text = html.slice( nextIndex, tagIndex );
- if ( cdata ) {
- cdata.push( text );
- } else {
- callbacks.onText( text );
- }
- }
- nextIndex = RE_PART.lastIndex;
- if ( (tagName = match[1]) ) {
- tagName = tagName.toLowerCase();
- if ( cdata && tagName == cdata._tag_name ) {
- callbacks.onCDATA( cdata.join( '' ) );
- cdata = null;
- }
- if ( !cdata ) {
- callbacks.onTagClose( tagName );
- continue;
- }
- }
- if ( cdata ) {
- cdata.push( match[0] );
- continue;
- }
- if ( (tagName = match[3]) ) {
- if ( /="/.test( tagName ) ) {
- continue;
- }
- tagName = tagName.toLowerCase();
- var attrPart = match[4],
- attrMatch,
- attrMap = {},
- selfClosing = attrPart && attrPart.slice( -1 ) == '/';
- if ( attrPart ) {
- RE_ATTR.exec( "" );
- while ( (attrMatch = RE_ATTR.exec( attrPart )) ) {
- var attrName = attrMatch[1].toLowerCase(),
- attrValue = attrMatch[2] || attrMatch[3] || attrMatch[4] || '';
- if ( !attrValue && EMPTY_ATTR[attrName] ) {
- attrValue = attrName;
- }
- if ( attrName == 'style' ) {
- if ( ie && version <= 6 ) {
- attrValue = attrValue.replace( /(?!;)\s*([\w-]+):/g, function ( m, p1 ) {
- return p1.toLowerCase() + ':';
- } );
- }
- }
- //没有值的属性不添加
- if ( attrValue ) {
- attrMap[attrName] = attrValue.replace( /:\s*/g, ':' )
- }
- }
- }
- callbacks.onTagOpen( tagName, attrMap, selfClosing );
- if ( !cdata && CDATA_TAG[tagName] ) {
- cdata = [];
- cdata._tag_name = tagName;
- }
- continue;
- }
- if ( (tagName = match[2]) ) {
- callbacks.onComment( tagName );
- }
- }
- if ( html.length > nextIndex ) {
- callbacks.onText( html.slice( nextIndex, html.length ) );
- }
- }
- return function ( html, forceDtd ) {
- var fragment = {
- type: 'fragment',
- parent: null,
- children: []
- };
- var currentNode = fragment;
- function addChild( node ) {
- node.parent = currentNode;
- currentNode.children.push( node );
- }
- function addElement( element, open ) {
- var node = element;
- // 遇到结构化标签的时候
- if ( NEED_PARENT_TAG[node.tag] ) {
- // 考虑这种情况的时候, 结束之前的标签
- // e.g. <table><tr><td>12312`<tr>`4566
- while ( NEED_PARENT_TAG[currentNode.tag] && NEED_PARENT_TAG[currentNode.tag][node.tag] ) {
- currentNode = currentNode.parent;
- }
- // 如果前一个标签和这个标签是同一级, 结束之前的标签
- // e.g. <ul><li>123<li>
- if ( currentNode.tag == node.tag ) {
- currentNode = currentNode.parent;
- }
- // 向上补齐父标签
- while ( NEED_PARENT_TAG[node.tag] ) {
- if ( NEED_PARENT_TAG[node.tag][currentNode.tag] ) break;
- node = node.parent = {
- type: 'element',
- tag: NEED_PARENT_TAG[node.tag]['$'],
- attributes: {},
- children: [node]
- };
- }
- }
- if ( forceDtd ) {
- // 如果遇到这个标签不能放在前一个标签内部,则结束前一个标签,span单独处理
- while ( dtd[node.tag] && !(currentNode.tag == 'span' ? utils.extend( dtd['strong'], {'a':1,'A':1} ) : (dtd[currentNode.tag] || dtd['div']))[node.tag] ) {
- if ( tagEnd( currentNode ) ) continue;
- if ( !currentNode.parent ) break;
- currentNode = currentNode.parent;
- }
- }
- node.parent = currentNode;
- currentNode.children.push( node );
- if ( open ) {
- currentNode = element;
- }
- if ( element.attributes.style ) {
- element.attributes.style = element.attributes.style.toLowerCase();
- }
- return element;
- }
- // 结束一个标签的时候,需要判断一下它是否缺少子标签
- // e.g. <table></table>
- function tagEnd( node ) {
- var needTag;
- if ( !node.children.length && (needTag = NEED_CHILD_TAG[node.tag]) ) {
- addElement( {
- type: 'element',
- tag: needTag,
- attributes: {},
- children: []
- }, true );
- return true;
- }
- return false;
- }
- parse( html, {
- onText: function ( text ) {
- while ( !(dtd[currentNode.tag] || dtd['div'])['#'] ) {
- //节点之间的空白不能当作节点处理
- // if(/^[ \t\r\n]+$/.test( text )){
- // return;
- // }
- if ( tagEnd( currentNode ) ) continue;
- currentNode = currentNode.parent;
- }
- //if(/^[ \t\n\r]*/.test(text))
- addChild( {
- type: 'text',
- data: text
- } );
- },
- onComment: function ( text ) {
- addChild( {
- type: 'comment',
- data: text
- } );
- },
- onCDATA: function ( text ) {
- while ( !(dtd[currentNode.tag] || dtd['div'])['#'] ) {
- if ( tagEnd( currentNode ) ) continue;
- currentNode = currentNode.parent;
- }
- addChild( {
- type: 'cdata',
- data: text
- } );
- },
- onTagOpen: function ( tag, attrs, closed ) {
- closed = closed || EMPTY_TAG[tag] ;
- addElement( {
- type: 'element',
- tag: tag,
- attributes: attrs,
- closed: closed,
- children: []
- }, !closed );
- },
- onTagClose: function ( tag ) {
- var node = currentNode;
- // 向上找匹配的标签, 这里不考虑dtd的情况是因为tagOpen的时候已经处理过了, 这里不会遇到
- while ( node && tag != node.tag ) {
- node = node.parent;
- }
- if ( node ) {
- // 关闭中间的标签
- for ( var tnode = currentNode; tnode !== node.parent; tnode = tnode.parent ) {
- tagEnd( tnode );
- }
- //去掉空白的inline节点
- //分页,锚点保留
- //|| dtd.$removeEmptyBlock[node.tag])
- // if ( !node.children.length && dtd.$removeEmpty[node.tag] && !node.attributes.anchorname && node.attributes['class'] != 'pagebreak' && node.tag != 'a') {
- //
- // node.parent.children.pop();
- // }
- currentNode = node.parent;
- } else {
- // 如果没有找到开始标签, 则创建新标签
- // eg. </div> => <div></div>
- //针对视屏网站embed会给结束符,这里特殊处理一下
- if ( !(dtd.$removeEmpty[tag] || dtd.$removeEmptyBlock[tag] || tag == 'embed') ) {
- node = {
- type: 'element',
- tag: tag,
- attributes: {},
- children: []
- };
- addElement( node, true );
- tagEnd( node );
- currentNode = node.parent;
- }
- }
- }
- } );
- // 处理这种情况, 只有开始标签没有结束标签的情况, 需要关闭开始标签
- // eg. <table>
- while ( currentNode !== fragment ) {
- tagEnd( currentNode );
- currentNode = currentNode.parent;
- }
- return fragment;
- };
- }();
- var unhtml1 = function () {
- var map = { '<': '<', '>': '>', '"': '"', "'": ''' };
- function rep( m ) {
- return map[m];
- }
- return function ( str ) {
- str = str + '';
- return str ? str.replace( /[<>"']/g, rep ) : '';
- };
- }();
- var toHTML = function () {
- function printChildren( node, pasteplain ) {
- var children = node.children;
- var buff = [];
- for ( var i = 0,ci; ci = children[i]; i++ ) {
- buff.push( toHTML( ci, pasteplain ) );
- }
- return buff.join( '' );
- }
- function printAttrs( attrs ) {
- var buff = [];
- for ( var k in attrs ) {
- var value = attrs[k];
- if(k == 'style'){
- //pt==>px
- value = ptToPx(value);
- //color rgb ==> hex
- if(/rgba?\s*\([^)]*\)/.test(value)){
- value = value.replace( /rgba?\s*\(([^)]*)\)/g, function( str ) {
- return utils.fixColor('color',str);
- } )
- }
- //过滤掉所有的white-space,在纯文本编辑器里粘贴过来的内容,到chrome中会带有span和white-space属性,导致出现不能折行的情况
- //所以在这里去掉这个属性
- attrs[k] = utils.optCss(value.replace(/windowtext/g,'#000'))
- .replace(/white-space[^;]+;/g,'');
- if(!attrs[k]){
- continue;
- }
- }
- buff.push( k + '="' + unhtml1( attrs[k] ) + '"' );
- }
- return buff.join( ' ' )
- }
- function printData( node, notTrans ) {
- //trace:1399 输入html代码时空格转换成为
- //node.data.replace(/ /g,' ') 针对pre中的空格和出现的 把他们在得到的html代码中都转换成为空格,为了在源码模式下显示为空格而不是
- return notTrans ? node.data.replace(/ /g,' ') : unhtml1( node.data ).replace(/ /g,' ');
- }
- //纯文本模式下标签转换
- var transHtml = {
- 'li':'p',
- 'h1':'p','h2':'p','h3':'p','h4':'p','h5':'p','h6':'p',
- 'tr':'p',
- 'br':'br',
- 'div':'p',
- 'p':'p'//trace:1398 碰到p标签自己要加上p,否则transHtml[tag]是undefined
- };
- var clearTagName ={
- 'table':1,
- 'tbody':1,
- 'ol':1,
- 'ul':1,
- 'dt':1
- }
- function printElement( node, pasteplain ) {
- if ( node.type == 'element' && !node.children.length && (dtd.$removeEmpty[node.tag]) && node.tag != 'a' && utils.isEmptyObject(node.attributes) && autoClearEmptyNode) {// 锚点保留
- return html;
- }
- var tag = node.tag;
- if ( pasteplain && tag == 'td' ) {
- if ( !html ) html = '';
- html += printChildren( node, pasteplain ) + ' ';
- } else {
- var attrs = printAttrs( node.attributes );
- var html = pasteplain && clearTagName[tag] ? '' :
- '<' + (pasteplain && transHtml[tag] !==undefined? transHtml[tag] : tag) + (attrs ? ' ' + attrs : '') + (EMPTY_TAG[tag] ? ' />' : '>');
- if ( !EMPTY_TAG[tag] ) {
- //trace:1627 ,2070
- //p标签为空,将不占位这里占位符不起作用,用 或者br
- if( tag == 'p' && !node.children.length){
- html += browser.ie ? ' ' : '<br/>';
- }
- html += printChildren( node, pasteplain );
- html +=(pasteplain && clearTagName[tag] ? '' : '</' + (pasteplain && transHtml[tag]!==undefined? transHtml[tag] : tag) + '>');
- }
- }
- return html;
- }
- return function ( node, pasteplain ) {
- if ( node.type == 'fragment' ) {
- return printChildren( node, pasteplain );
- } else if ( node.type == 'element' ) {
- return printElement( node, pasteplain );
- } else if ( node.type == 'text' || node.type == 'cdata' ) {
- return printData( node, dtd.$notTransContent[node.parent.tag] );
- } else if ( node.type == 'comment' ) {
- return '<!--' + node.data + '-->';
- }
- return '';
- };
- }();
- var NODE_NAME_MAP = {
- 'text': '#text',
- 'comment': '#comment',
- 'cdata': '#cdata-section',
- 'fragment': '#document-fragment'
- };
- //写入编辑器时,调用,进行转换操作
- function transNode( node, word_img_flag ) {
- var sizeMap = [0, 10, 12, 16, 18, 24, 32, 48],
- attr,
- indexOf = utils.indexOf;
- switch ( node.tag ) {
- case 'script':
- node.tag = 'div';
- node.attributes._ue_org_tagName = 'script';
- node.attributes._ue_div_script = 1;
- node.attributes._ue_script_data = node.children[0] ? encodeURIComponent(node.children[0].data) : '';
- node.attributes._ue_custom_node_ = 1;
- node.children = [];
- break;
- case 'style':
- node.tag = 'div';
- node.attributes._ue_div_style = 1;
- node.attributes._ue_org_tagName = 'style';
- node.attributes._ue_style_data = node.children[0] ? encodeURIComponent(node.children[0].data) : '';
- node.attributes._ue_custom_node_ = 1;
- node.children = [];
- break;
- case 'img':
- //todo base64暂时去掉,后边做远程图片上传后,干掉这个
- if(node.attributes.src && /^data:/.test(node.attributes.src)){
- return {
- type : 'fragment',
- children:[]
- }
- }
- if ( node.attributes.src && /^(?:file)/.test( node.attributes.src ) ) {
- if ( !/(gif|bmp|png|jpg|jpeg)$/.test( node.attributes.src ) ) {
- return {
- type : 'fragment',
- children:[]
- }
- }
- node.attributes.word_img = node.attributes.src;
- node.attributes.src = me.options.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif';
- var flag = parseInt(node.attributes.width)<128||parseInt(node.attributes.height)<43;
- node.attributes.style="background:url(" + (flag? me.options.themePath+me.options.theme +"/images/word.gif":me.options.langPath+me.options.lang + "/images/localimage.png")+") no-repeat center center;border:1px solid #ddd";
- //node.attributes.style = 'width:395px;height:173px;';
- word_img_flag && (word_img_flag.flag = 1);
- }
- if(browser.ie && browser.version < 7 )
- node.attributes.orgSrc = node.attributes.src;
- node.attributes.data_ue_src = node.attributes.data_ue_src || node.attributes.src;
- break;
- case 'li':
- var child = node.children[0];
- if ( !child || child.type != 'element' || child.tag != 'p' && dtd.p[child.tag] ) {
- var tmpPNode = {
- type: 'element',
- tag: 'p',
- attributes: {},
- parent : node
- };
- tmpPNode.children = child ? node.children :[
- browser.ie ? {
- type:'text',
- data:domUtils.fillChar,
- parent : tmpPNode
- }:
- {
- type : 'element',
- tag : 'br',
- attributes:{},
- closed: true,
- children: [],
- parent : tmpPNode
- }
- ];
- node.children = [tmpPNode];
- }
- break;
- case 'table':
- case 'td':
- optStyle( node );
- break;
- case 'a'://锚点,a==>img
- if ( node.attributes['anchorname'] ) {
- node.tag = 'img';
- node.attributes = {
- 'class' : 'anchorclass',
- 'anchorname':node.attributes['name']
- };
- node.closed = 1;
- }
- node.attributes.href && (node.attributes.data_ue_src = node.attributes.href);
- break;
- case 'b':
- node.tag = node.name = 'strong';
- break;
- case 'i':
- node.tag = node.name = 'em';
- break;
- case 'u':
- node.tag = node.name = 'span';
- node.attributes.style = (node.attributes.style || '') + ';text-decoration:underline;';
- break;
- case 's':
- case 'del':
- node.tag = node.name = 'span';
- node.attributes.style = (node.attributes.style || '') + ';text-decoration:line-through;';
- if ( node.children.length == 1 ) {
- child = node.children[0];
- if ( child.tag == node.tag ) {
- node.attributes.style += ";" + child.attributes.style;
- node.children = child.children;
- }
- }
- break;
- case 'span':
- var style = node.attributes.style;
- if ( style ) {
- if ( !node.attributes.style || browser.webkit && style == "white-space:nowrap;") {
- delete node.attributes.style;
- }
- }
- //针对ff3.6span的样式不能正确继承的修复
- if(browser.gecko && browser.version <= 10902 && node.parent){
- var parent = node.parent;
- if(parent.tag == 'span' && parent.attributes && parent.attributes.style){
- node.attributes.style = parent.attributes.style + ';' + node.attributes.style;
- }
- }
- if ( utils.isEmptyObject( node.attributes ) && autoClearEmptyNode) {
- node.type = 'fragment'
- }
- break;
- case 'font':
- node.tag = node.name = 'span';
- attr = node.attributes;
- node.attributes = {
- 'style': (attr.size ? 'font-size:' + (sizeMap[attr.size] || 12) + 'px' : '')
- + ';' + (attr.color ? 'color:'+ attr.color : '')
- + ';' + (attr.face ? 'font-family:'+ attr.face : '')
- + ';' + (attr.style||'')
- };
- while(node.parent.tag == node.tag && node.parent.children.length == 1){
- node.attributes.style && (node.parent.attributes.style ? (node.parent.attributes.style += ";" + node.attributes.style) : (node.parent.attributes.style = node.attributes.style));
- node.parent.children = node.children;
- node = node.parent;
- }
- break;
- case 'p':
- if ( node.attributes.align ) {
- node.attributes.style = (node.attributes.style || '') + ';text-align:' +
- node.attributes.align + ';';
- delete node.attributes.align;
- }
- }
- return node;
- }
- function optStyle( node ) {
- if ( ie && node.attributes.style ) {
- var style = node.attributes.style;
- node.attributes.style = style.replace(/;\s*/g,';');
- node.attributes.style = node.attributes.style.replace( /^\s*|\s*$/, '' )
- }
- }
- //getContent调用转换
- function transOutNode( node ) {
- switch ( node.tag ) {
- case 'div' :
- if(node.attributes._ue_div_script){
- node.tag = 'script';
- node.children = [{type:'cdata',data:node.attributes._ue_script_data?decodeURIComponent(node.attributes._ue_script_data):'',parent:node}];
- delete node.attributes._ue_div_script;
- delete node.attributes._ue_script_data;
- delete node.attributes._ue_custom_node_;
- delete node.attributes._ue_org_tagName;
- }
- if(node.attributes._ue_div_style){
- node.tag = 'style';
- node.children = [{type:'cdata',data:node.attributes._ue_style_data?decodeURIComponent(node.attributes._ue_style_data):'',parent:node}];
- delete node.attributes._ue_div_style;
- delete node.attributes._ue_style_data;
- delete node.attributes._ue_custom_node_;
- delete node.attributes._ue_org_tagName;
- }
- break;
- case 'table':
- !node.attributes.style && delete node.attributes.style;
- if ( ie && node.attributes.style ) {
- optStyle( node );
- }
- break;
- case 'td':
- case 'th':
- if ( /display\s*:\s*none/i.test( node.attributes.style ) ) {
- return {
- type: 'fragment',
- children: []
- };
- }
- if ( ie && !node.children.length ) {
- var txtNode = {
- type: 'text',
- data:domUtils.fillChar,
- parent : node
- };
- node.children[0] = txtNode;
- }
- if ( ie && node.attributes.style ) {
- optStyle( node );
- }
- break;
- case 'img'://锚点,img==>a
- if ( node.attributes.anchorname ) {
- node.tag = 'a';
- node.attributes = {
- name : node.attributes.anchorname,
- anchorname : 1
- };
- node.closed = null;
- }else{
- if(node.attributes.data_ue_src){
- node.attributes.src = node.attributes.data_ue_src;
- delete node.attributes.data_ue_src;
- }
- }
- break;
- case 'a':
- if(node.attributes.data_ue_src){
- node.attributes.href = node.attributes.data_ue_src;
- delete node.attributes.data_ue_src;
- }
- }
- return node;
- }
- function childrenAccept( node, visit, ctx ) {
- if ( !node.children || !node.children.length ) {
- return node;
- }
- var children = node.children;
- for ( var i = 0; i < children.length; i++ ) {
- var newNode = visit( children[i], ctx );
- if ( newNode.type == 'fragment' ) {
- var args = [i, 1];
- args.push.apply( args, newNode.children );
- children.splice.apply( children, args );
- //节点为空的就干掉,不然后边的补全操作会添加多余的节点
- if ( !children.length ) {
- node = {
- type: 'fragment',
- children: []
- }
- }
- i --;
- } else {
- children[i] = newNode;
- }
- }
- return node;
- }
- function Serialize( rules ) {
- this.rules = rules;
- }
- Serialize.prototype = {
- // NOTE: selector目前只支持tagName
- rules: null,
- // NOTE: node必须是fragment
- filter: function ( node, rules, modify ) {
- rules = rules || this.rules;
- var whiteList = rules && rules.whiteList;
- var blackList = rules && rules.blackList;
- function visitNode( node, parent ) {
- node.name = node.type == 'element' ?
- node.tag : NODE_NAME_MAP[node.type];
- if ( parent == null ) {
- return childrenAccept( node, visitNode, node );
- }
- if ( blackList && (blackList[node.name]|| (node.attributes && node.attributes._ue_org_tagName && blackList[node.attributes._ue_org_tagName]))) {
- modify && (modify.flag = 1);
- return {
- type: 'fragment',
- children: []
- };
- }
- if ( whiteList ) {
- if ( node.type == 'element' ) {
- if ( parent.type == 'fragment' ? whiteList[node.name] : whiteList[node.name] && whiteList[parent.name][node.name] ) {
- var props;
- if ( (props = whiteList[node.name].$) ) {
- var oldAttrs = node.attributes;
- var newAttrs = {};
- for ( var k in props ) {
- if ( oldAttrs[k] ) {
- newAttrs[k] = oldAttrs[k];
- }
- }
- node.attributes = newAttrs;
- }
- } else {
- modify && (modify.flag = 1);
- node.type = 'fragment';
- // NOTE: 这里算是一个hack
- node.name = parent.name;
- }
- } else {
- // NOTE: 文本默认允许
- }
- }
- if ( blackList || whiteList ) {
- childrenAccept( node, visitNode, node );
- }
- return node;
- }
- return visitNode( node, null );
- },
- transformInput: function ( node, word_img_flag ) {
- function visitNode( node ) {
- node = transNode( node, word_img_flag );
- node = childrenAccept( node, visitNode, node );
- if ( me.options.pageBreakTag && node.type == 'text' && node.data.replace( /\s/g, '' ) == me.options.pageBreakTag ) {
- node.type = 'element';
- node.name = node.tag = 'hr';
- delete node.data;
- node.attributes = {
- 'class' : 'pagebreak',
- noshade:"noshade",
- size:"5",
- 'unselectable' : 'on',
- 'style' : 'moz-user-select:none;-khtml-user-select: none;'
- };
- node.children = [];
- }
- //去掉多余的空格和换行
- if(node.type == 'text' && !dtd.$notTransContent[node.parent.tag]){
- node.data = node.data.replace(/[\r\t\n]*/g,'')//.replace(/[ ]*$/g,'')
- }
- return node;
- }
- return visitNode( node );
- },
- transformOutput: function ( node ) {
- function visitNode( node ) {
- if ( node.tag == 'hr' && node.attributes['class'] == 'pagebreak' ) {
- delete node.tag;
- node.type = 'text';
- node.data = me.options.pageBreakTag;
- delete node.children;
- }
- node = transOutNode( node );
- node = childrenAccept( node, visitNode, node );
- return node;
- }
- return visitNode( node );
- },
- toHTML: toHTML,
- parseHTML: parseHTML,
- word: UE.filterWord
- };
- me.serialize = new Serialize( me.options.serialize || {});
- UE.serialize = new Serialize( {} );
- };
- ///import core
- ///import plugins/inserthtml.js
- ///commands 视频
- ///commandsName InsertVideo
- ///commandsTitle 插入视频
- ///commandsDialog dialogs\video
- UE.plugins['video'] = function (){
- var me =this,
- div;
- /**
- * 创建插入视频字符窜
- * @param url 视频地址
- * @param width 视频宽度
- * @param height 视频高度
- * @param align 视频对齐
- * @param toEmbed 是否以flash代替显示
- * @param addParagraph 是否需要添加P 标签
- */
- function creatInsertStr(url,width,height,align,toEmbed,addParagraph){
- return !toEmbed ?
- (addParagraph? ('<p '+ (align && align !="none" ? ( align == "center"? ' style="text-align:center;" ':' style="float:"'+ align ) : '') + '>'): '') +
- '<img align="'+align+'" width="'+ width +'" height="' + height + '" _url="'+url+'" class="edui-faked-video"' +
- ' src="' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif" style="background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;" />' +
- (addParagraph?'</p>':'')
- :
- '<embed type="application/x-shockwave-flash" class="edui-faked-video" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
- ' src="' + url + '" width="' + width + '" height="' + height + '" align="' + align + '"' +
- ( align && align !="none" ? ' style= "'+ ( align == "center"? "display:block;":" float: "+ align ) + '"' :'' ) +
- ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >';
- }
- function switchImgAndEmbed(img2embed){
- var tmpdiv,
- nodes =domUtils.getElementsByTagName(me.document, !img2embed ? "embed" : "img");
- for(var i=0,node;node = nodes[i++];){
- if(node.className!="edui-faked-video"){
- continue;
- }
- tmpdiv = me.document.createElement("div");
- //先看float在看align,浮动有的是时候是在float上定义的
- var align = domUtils.getComputedStyle(node,'float');
- align = align == 'none' ? (node.getAttribute('align') || '') : align;
- tmpdiv.innerHTML = creatInsertStr(img2embed ? node.getAttribute("_url"):node.getAttribute("src"),node.width,node.height,align,img2embed);
- node.parentNode.replaceChild(tmpdiv.firstChild,node);
- }
- }
- me.addListener("beforegetcontent",function(){
- switchImgAndEmbed(true);
- });
- me.addListener('aftersetcontent',function(){
- switchImgAndEmbed(false);
- });
- me.addListener('aftergetcontent',function(cmdName){
- if(cmdName == 'aftergetcontent' && me.queryCommandState('source')){
- return;
- }
- switchImgAndEmbed(false);
- });
- me.commands["insertvideo"] = {
- execCommand: function (cmd, videoObjs){
- videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs];
- var html = [];
- for(var i=0,vi,len = videoObjs.length;i<len;i++){
- vi = videoObjs[i];
- html.push(creatInsertStr( vi.url, vi.width || 420, vi.height || 280, vi.align||"none",false,true));
- }
- me.execCommand("inserthtml",html.join(""));
- },
- queryCommandState : function(){
- var img = me.selection.getRange().getClosedNode(),
- flag = img && (img.className == "edui-faked-video");
- return flag ? 1 : 0;
- }
- };
- };
- /**
- * Created with JetBrains PhpStorm.
- * User: taoqili
- * Date: 12-10-12
- * Time: 上午10:05
- * To change this template use File | Settings | File Templates.
- */
- UE.plugins['table'] = function () {
- var me = this,
- debug = true;
- function showError(e) {
- if (debug) throw e;
- }
- //处理拖动及框选相关方法
- var startTd = null, //鼠标按下时的锚点td
- currentTd = null, //当前鼠标经过时的td
- onDrag = "", //指示当前拖动状态,其值可为"","h","v" ,分别表示未拖动状态,横向拖动状态,纵向拖动状态,用于鼠标移动过程中的判断
- onBorder = false, //检测鼠标按下时是否处在单元格边缘位置
- dragButton = null,
- dragOver = false,
- dragLine = null, //模拟的拖动线
- dragTd = null; //发生拖动的目标td
- var mousedown = false,
- //todo 判断混乱模式
- needIEHack = true;
- me.setOpt({
- 'maxColNum':20,
- 'maxRowNum':100,
- 'defaultCols':5,
- 'defaultRows':5,
- 'tdvalign':'top',
- 'cursorpath':me.options.UEDITOR_HOME_URL + "themes/default/images/cursor_",
- 'tableDragable':false
- });
- me.getUETable = getUETable;
- var commands = {
- 'deletetable':1,
- 'inserttable':1,
- 'signset':1,
- 'cellvalign':1,
- 'insertcaption':1,
- 'deletecaption':1,
- 'inserttitle':1,
- 'deletetitle':1,
- "mergeright":1,
- "mergedown":1,
- "mergecells":1,
- "insertrow":1,
- "insertrownext":1,
- "deleterow":1,
- "insertcol":1,
- "insertcolnext":1,
- "deletecol":1,
- "splittocells":1,
- "splittorows":1,
- "splittocols":1,
- "adaptbytext":1,
- "adaptbywindow":1,
- "adaptbycustomer":1,
- "insertparagraph":1,
- "averagedistributecol":1,
- "averagedistributerow":1
- };
- me.ready(function () {
- utils.cssRule('table',
- //选中的td上的样式
- '.selectTdClass{background-color:#edf5fa !important}' +
- 'table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}' +
- //插入的表格的默认样式
- 'table{margin-bottom:10px;border-collapse:collapse;display:table;}' +
- 'td,th{ background:white; padding: 5px 10px;border: 1px solid #DDD;}' +
- 'caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}' +
- 'th{border-top:2px solid #BBB;background:#F7F7F7;}' +
- 'td p{margin:0;padding:0;}', me.document);
- var tableCopyList, isFullCol, isFullRow;
- //注册del/backspace事件
- me.addListener('keydown', function (cmd, evt) {
- var me = this;
- var keyCode = evt.keyCode || evt.which;
- if (keyCode == 8) {
- var ut = getUETableBySelected(me);
- if (ut && ut.selectedTds.length) {
- me.fireEvent('saveScene');
- if (ut.isFullCol()) {
- me.execCommand('deletecol')
- } else if (ut.isFullRow()) {
- me.execCommand('deleterow')
- } else {
- me.fireEvent('delcells');
- }
- domUtils.preventDefault(evt);
- }
- var caption = domUtils.findParentByTagName(me.selection.getStart(), 'caption', true),
- range = me.selection.getRange();
- if (range.collapsed && caption && isEmptyBlock(caption)) {
- me.fireEvent('saveScene');
- var table = caption.parentNode;
- domUtils.remove(caption);
- if (table) {
- range.setStart(table.rows[0].cells[0], 0).setCursor(false, true);
- }
- }
- me.fireEvent('saveScene');
- }
- if (keyCode == 46) {
- ut = getUETableBySelected(me);
- if (ut) {
- me.fireEvent('saveScene');
- for (var i = 0, ci; ci = ut.selectedTds[i++];) {
- domUtils.fillNode(me.document, ci)
- }
- me.fireEvent('saveScene');
- domUtils.preventDefault(evt);
- }
- }
- if (keyCode == 13) {
- var rng = me.selection.getRange(),
- caption = domUtils.findParentByTagName(rng.startContainer, 'caption', true);
- if (caption) {
- var table = domUtils.findParentByTagName(caption, 'table');
- if (!rng.collapsed) {
- rng.deleteContents();
- me.fireEvent('saveScene');
- } else {
- if (caption) {
- rng.setStart(table.rows[0].cells[0], 0).setCursor(false, true);
- }
- }
- domUtils.preventDefault(evt);
- return;
- }
- if (rng.collapsed) {
- var table = domUtils.findParentByTagName(rng.startContainer, 'table');
- if (table) {
- var cell = table.rows[0].cells[0],
- start = domUtils.findParentByTagName(me.selection.getStart(), ['td', 'th'], true),
- preNode = table.previousSibling;
- if (cell === start && (!preNode || preNode.nodeType == 1 && preNode.tagName == 'TABLE' ) && domUtils.isStartInblock(rng)) {
- me.execCommand('insertparagraphbeforetable');
- domUtils.preventDefault(evt);
- }
- }
- }
- }
- if ((evt.ctrlKey || evt.metaKey) && evt.keyCode == '67') {
- tableCopyList = null;
- table = getUETableBySelected(me);
- if (table) {
- var tds = table.selectedTds;
- isFullCol = table.isFullCol();
- isFullRow = table.isFullRow();
- tableCopyList = [
- [cloneCell(tds[0])]
- ];
- for (var i = 1, ci; ci = tds[i]; i++) {
- if (ci.parentNode !== tds[i - 1].parentNode) {
- tableCopyList.push([cloneCell(ci)])
- } else {
- tableCopyList[tableCopyList.length - 1].push(cloneCell(ci))
- }
- }
- }
- }
- });
- me.addListener('beforepaste', function (cmd, html) {
- var me = this;
- var rng = me.selection.getRange();
- if (domUtils.findParentByTagName(rng.startContainer, 'caption', true)) {
- var div = me.document.createElement("div");
- div.innerHTML = html.html;
- html.html = div[browser.ie ? 'innerText' : 'textContent'];
- return;
- }
- var table = getUETableBySelected(me);
- if (tableCopyList) {
- me.fireEvent('saveScene');
- var rng = me.selection.getRange();
- var td = domUtils.findParentByTagName(rng.startContainer, ['td', 'th'], true), tmpNode, preNode;
- if (td) {
- var ut = getUETable(td);
- if (isFullRow) {
- var rowIndex = ut.getCellInfo(td).rowIndex;
- if (td.tagName == 'TH') {
- rowIndex++;
- }
- for (var i = 0, ci; ci = tableCopyList[i++];) {
- var tr = ut.insertRow(rowIndex++, "td");
- for (var j = 0, cj; cj = ci[j]; j++) {
- var cell = tr.cells[j];
- if (!cell) {
- cell = tr.insertCell(j)
- }
- cell.innerHTML = cj.innerHTML;
- cj.getAttribute('width') && cell.setAttribute('width', cj.getAttribute('width'));
- cj.getAttribute('vAlign') && cell.setAttribute('vAlign', cj.getAttribute('vAlign'));
- cj.getAttribute('align') && cell.setAttribute('align', cj.getAttribute('align'));
- cj.style.cssText && (cell.style.cssText = cj.style.cssText)
- }
- for (var j = 0, cj; cj = tr.cells[j]; j++) {
- if (!ci[j])
- break;
- cj.innerHTML = ci[j].innerHTML;
- ci[j].getAttribute('width') && cj.setAttribute('width', ci[j].getAttribute('width'));
- ci[j].getAttribute('vAlign') && cj.setAttribute('vAlign', ci[j].getAttribute('vAlign'));
- ci[j].getAttribute('align') && cj.setAttribute('align', ci[j].getAttribute('align'));
- ci[j].style.cssText && (cj.style.cssText = ci[j].style.cssText)
- }
- }
- } else {
- if (isFullCol) {
- cellInfo = ut.getCellInfo(td);
- var maxColNum = 0;
- for (var j = 0, ci = tableCopyList[0], cj; cj = ci[j++];) {
- maxColNum += cj.colSpan || 1;
- }
- me.__hasEnterExecCommand = true;
- for (i = 0; i < maxColNum; i++) {
- me.execCommand('insertcol');
- }
- me.__hasEnterExecCommand = false;
- td = ut.table.rows[0].cells[cellInfo.cellIndex];
- if (td.tagName == 'TH') {
- td = ut.table.rows[1].cells[cellInfo.cellIndex];
- }
- }
- for (var i = 0, ci; ci = tableCopyList[i++];) {
- tmpNode = td;
- for (var j = 0, cj; cj = ci[j++];) {
- if (td) {
- td.innerHTML = cj.innerHTML;
- //todo 定制处理
- cj.getAttribute('width') && td.setAttribute('width', cj.getAttribute('width'));
- cj.getAttribute('vAlign') && td.setAttribute('vAlign', cj.getAttribute('vAlign'));
- cj.getAttribute('align') && td.setAttribute('align', cj.getAttribute('align'));
- cj.style.cssText && (td.style.cssText = cj.style.cssText);
- preNode = td;
- td = td.nextSibling;
- } else {
- var cloneTd = cj.cloneNode(true);
- domUtils.removeAttributes(cloneTd, ['class', 'rowSpan', 'colSpan']);
- preNode.parentNode.appendChild(cloneTd)
- }
- }
- td = ut.getNextCell(tmpNode, true, true);
- if (!tableCopyList[i])
- break;
- if (!td) {
- var cellInfo = ut.getCellInfo(tmpNode);
- ut.table.insertRow(ut.table.rows.length);
- ut.update();
- td = ut.getVSideCell(tmpNode, true);
- }
- }
- }
- ut.update();
- } else {
- table = me.document.createElement('table');
- for (var i = 0, ci; ci = tableCopyList[i++];) {
- var tr = table.insertRow(table.rows.length);
- for (var j = 0, cj; cj = ci[j++];) {
- cloneTd = cloneCell(cj);
- domUtils.removeAttributes(cloneTd, ['class']);
- tr.appendChild(cloneTd)
- }
- if (j == 2 && cloneTd.rowSpan > 1) {
- cloneTd.rowSpan = 1;
- }
- }
- var defaultValue = getDefaultValue(me),
- width = me.body.offsetWidth -
- (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0);
- me.execCommand('insertHTML', '<table ' +
- ( isFullCol && isFullRow ? 'width="' + width + '"' : '') +
- '>' + table.innerHTML.replace(/>\s*</g, '><').replace(/\bth\b/gi, "td") + '</table>')
- }
- me.fireEvent('contentchange');
- me.fireEvent('saveScene');
- html.html = '';
- } else {
- var div = me.document.createElement("div"), tables;
- div.innerHTML = html.html;
- tables = div.getElementsByTagName("table");
- if (domUtils.findParentByTagName(me.selection.getStart(), 'table')) {
- utils.each(tables, function (t) {
- domUtils.remove(t)
- });
- if (domUtils.findParentByTagName(me.selection.getStart(), 'caption', true)) {
- div.innerHTML = div[browser.ie ? 'innerText' : 'textContent'];
- }
- } else {
- utils.each(tables, function (table) {
- removeStyleSize(table, true);
- domUtils.removeAttributes(table, ['style', 'border']);
- utils.each(domUtils.getElementsByTagName(table, "td"), function (td) {
- if (isEmptyBlock(td)) {
- domUtils.fillNode(me.document, td);
- }
- removeStyleSize(td, true);
- // domUtils.removeAttributes(td, ['style'])
- });
- });
- }
- html.html = div.innerHTML;
- }
- });
- me.addListener('afterpaste', function () {
- utils.each(domUtils.getElementsByTagName(me.body, "table"), function (table) {
- if (table.offsetWidth > me.body.offsetWidth) {
- var defaultValue = getDefaultValue(me, table);
- table.style.width = me.body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0) + 'px'
- }
- })
- });
- me.addListener('blur', function () {
- tableCopyList = null;
- });
- var timer;
- me.addListener('keydown', function () {
- clearTimeout(timer);
- timer = setTimeout(function () {
- var rng = me.selection.getRange(),
- cell = domUtils.findParentByTagName(rng.startContainer, ['th', 'td'], true);
- if (cell) {
- var table = cell.parentNode.parentNode.parentNode;
- if (table.offsetWidth > table.getAttribute("width")) {
- cell.style.wordBreak = "break-all";
- }
- }
- }, 100);
- });
- me.addListener("selectionchange", function () {
- toggleDragableState(me, false, "", null);
- });
- //内容变化时触发索引更新
- //todo 可否考虑标记检测,如果不涉及表格的变化就不进行索引重建和更新
- me.addListener("contentchange", function () {
- var me = this;
- //尽可能排除一些不需要更新的状况
- hideDragLine(me);
- if (getUETableBySelected(me))return;
- var rng = me.selection.getRange();
- var start = rng.startContainer;
- start = domUtils.findParentByTagName(start, ['td', 'th'], true);
- utils.each(domUtils.getElementsByTagName(me.document, 'table'), function (table) {
- if (me.fireEvent("excludetable", table) === true) return;
- table.ueTable = new UETable(table);
- utils.each(domUtils.getElementsByTagName(me.document, 'td'), function (td) {
- if (domUtils.isEmptyBlock(td) && td !== start) {
- domUtils.fillNode(me.document, td);
- if (browser.ie && browser.version == 6) {
- td.innerHTML = ' '
- }
- }
- });
- utils.each(domUtils.getElementsByTagName(me.document, 'th'), function (th) {
- if (domUtils.isEmptyBlock(th) && th !== start) {
- domUtils.fillNode(me.document, th);
- if (browser.ie && browser.version == 6) {
- th.innerHTML = ' '
- }
- }
- });
- table.onmousemove = function () {
- me.options.tableDragable && toggleDragButton(true, this, me);
- };
- table.onmouseout = function () {
- toggleDragableState(me, false, "", null);
- hideDragLine(me);
- };
- table.onclick = function (evt) {
- evt = me.window.event || evt;
- var target = getParentTdOrTh(evt.target || evt.srcElement);
- if (!target)return;
- var ut = getUETable(target),
- table = ut.table,
- cellInfo = ut.getCellInfo(target),
- cellsRange,
- rng = me.selection.getRange();
- // if ("topLeft" == inPosition(table, mouseCoords(evt))) {
- // cellsRange = ut.getCellsRange(ut.table.rows[0].cells[0], ut.getLastCell());
- // ut.setSelected(cellsRange);
- // return;
- // }
- // if ("bottomRight" == inPosition(table, mouseCoords(evt))) {
- //
- // return;
- // }
- if (inTableSide(table, target, evt, true)) {
- var endTdCol = ut.getCell(ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].rowIndex, ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].cellIndex);
- if (evt.shiftKey && ut.selectedTds.length) {
- if (ut.selectedTds[0] !== endTdCol) {
- cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdCol);
- ut.setSelected(cellsRange);
- } else {
- rng && rng.selectNodeContents(endTdCol).select();
- }
- } else {
- if (target !== endTdCol) {
- cellsRange = ut.getCellsRange(target, endTdCol);
- ut.setSelected(cellsRange);
- } else {
- rng && rng.selectNodeContents(endTdCol).select();
- }
- }
- return;
- }
- if (inTableSide(table, target, evt)) {
- var endTdRow = ut.getCell(ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].rowIndex, ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].cellIndex);
- if (evt.shiftKey && ut.selectedTds.length) {
- if (ut.selectedTds[0] !== endTdRow) {
- cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdRow);
- ut.setSelected(cellsRange);
- } else {
- rng && rng.selectNodeContents(endTdRow).select();
- }
- } else {
- if (target !== endTdRow) {
- cellsRange = ut.getCellsRange(target, endTdRow);
- ut.setSelected(cellsRange);
- } else {
- rng && rng.selectNodeContents(endTdRow).select();
- }
- }
- }
- };
- table.ondblclick = function (evt) {
- evt = me.window.event || evt;
- var target = getParentTdOrTh(evt.target || evt.srcElement);
- if (target) {
- var h;
- if (h = getRelation(target, mouseCoords(evt))) {
- if (h == 'h1') {
- h = 'h';
- if (inTableSide(domUtils.findParentByTagName(target, "table"), target, evt)) {
- me.execCommand('adaptbywindow');
- } else {
- target = getUETable(target).getPreviewCell(target);
- if (target) {
- var rng = me.selection.getRange();
- rng.selectNodeContents(target).setCursor(true, true)
- }
- }
- }
- h == 'h' && me.execCommand('adaptbytext');
- }
- }
- }
- });
- switchBoderColor(true);
- });
- //仅IE8以上支持
- if (!browser.ie || (browser.ie && browser.version > 7)) {
- domUtils.on(me.document, "mousemove", mouseMoveEvent);
- }
- domUtils.on(me.document, "mouseout", function (evt) {
- var target = evt.target || evt.srcElement;
- if (target.tagName == "TABLE") {
- toggleDragableState(me, false, "", null);
- }
- });
- me.addListener("mousedown", mouseDownEvent);
- me.addListener("mouseup", mouseUpEvent);
- var currentRowIndex = 0;
- me.addListener("mousedown", function () {
- currentRowIndex = 0;
- });
- me.addListener('tabkeydown', function () {
- var range = this.selection.getRange(),
- common = range.getCommonAncestor(true, true),
- table = domUtils.findParentByTagName(common, 'table');
- if (table) {
- if (domUtils.findParentByTagName(common, 'caption', true)) {
- var cell = domUtils.getElementsByTagName(table, 'th td');
- if (cell && cell.length) {
- range.setStart(cell[0], 0).setCursor(false, true)
- }
- } else {
- var cell = domUtils.findParentByTagName(common, ['td', 'th'], true),
- ua = getUETable(cell);
- currentRowIndex = cell.rowSpan > 1 ? currentRowIndex : ua.getCellInfo(cell).rowIndex;
- var nextCell = ua.getTabNextCell(cell, currentRowIndex);
- if (nextCell) {
- if (isEmptyBlock(nextCell)) {
- range.setStart(nextCell, 0).setCursor(false, true)
- } else {
- range.selectNodeContents(nextCell).select()
- }
- } else {
- me.fireEvent('saveScene');
- me.__hasEnterExecCommand = true;
- this.execCommand('insertrownext');
- me.__hasEnterExecCommand = false;
- range = this.selection.getRange();
- range.setStart(table.rows[table.rows.length - 1].cells[0], 0).setCursor();
- me.fireEvent('saveScene');
- }
- }
- return true;
- }
- });
- browser.ie && me.addListener('selectionchange', function () {
- toggleDragableState(this, false, "", null);
- });
- me.addListener("keydown", function (type, evt) {
- var me = this;
- //处理在表格的最后一个输入tab产生新的表格
- var keyCode = evt.keyCode || evt.which;
- if (keyCode == 8 || keyCode == 46) {
- return;
- }
- var notCtrlKey = !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey;
- notCtrlKey && removeSelectedClass(domUtils.getElementsByTagName(me.body, "td"));
- var ut = getUETableBySelected(me);
- if (!ut) return;
- notCtrlKey && ut.clearSelected();
- });
- me.addListener("beforegetcontent", function () {
- switchBoderColor(false);
- browser.ie && utils.each(me.document.getElementsByTagName('caption'), function (ci) {
- if (domUtils.isEmptyNode(ci)) {
- ci.innerHTML = ' '
- }
- });
- });
- me.addListener("aftergetcontent", function () {
- switchBoderColor(true);
- });
- me.addListener("getAllHtml", function () {
- removeSelectedClass(me.document.getElementsByTagName("td"));
- });
- //修正全屏状态下插入的表格宽度在非全屏状态下撑开编辑器的情况
- me.addListener("fullscreenchanged", function (type, fullscreen) {
- if (!fullscreen) {
- var ratio = this.body.offsetWidth / document.body.offsetWidth,
- tables = domUtils.getElementsByTagName(this.body, "table");
- utils.each(tables, function (table) {
- if (table.offsetWidth < me.body.offsetWidth) return false;
- var tds = domUtils.getElementsByTagName(table, "td"),
- backWidths = [];
- utils.each(tds, function (td) {
- backWidths.push(td.offsetWidth);
- });
- for (var i = 0, td; td = tds[i]; i++) {
- td.setAttribute("width", Math.floor(backWidths[i] * ratio));
- }
- table.setAttribute("width", Math.floor(getTableWidth(me, needIEHack, getDefaultValue(me))))
- });
- }
- });
- //重写execCommand命令,用于处理框选时的处理
- var oldExecCommand = me.execCommand;
- me.execCommand = function (cmd) {
- var me = this;
- cmd = cmd.toLowerCase();
- var ut = getUETableBySelected(me), tds,
- range = new dom.Range(me.document),
- cmdFun = me.commands[cmd] || UE.commands[cmd],
- result;
- if (!cmdFun) return;
- if (ut && !commands[cmd] && !cmdFun.notNeedUndo && !me.__hasEnterExecCommand) {
- me.__hasEnterExecCommand = true;
- me.fireEvent("beforeexeccommand", cmd);
- tds = ut.selectedTds;
- var lastState = -2, lastValue = -2, value, state;
- for (var i = 0, td; td = tds[i]; i++) {
- if (isEmptyBlock(td)) {
- range.setStart(td, 0).setCursor(false, true)
- } else {
- range.selectNodeContents(td).select(true);
- }
- state = me.queryCommandState(cmd);
- value = me.queryCommandValue(cmd);
- if (state != -1) {
- if (lastState !== state || lastValue !== value) {
- me._ignoreContentChange = true;
- result = oldExecCommand.apply(me, arguments);
- me._ignoreContentChange = false;
- }
- lastState = me.queryCommandState(cmd);
- lastValue = me.queryCommandValue(cmd);
- if (domUtils.isEmptyBlock(td)) {
- domUtils.fillNode(me.document, td)
- }
- }
- }
- range.setStart(tds[0], 0).shrinkBoundary(true).setCursor(false, true);
- me.fireEvent('contentchange');
- me.fireEvent("afterexeccommand", cmd);
- me.__hasEnterExecCommand = false;
- me._selectionChange();
- } else {
- result = oldExecCommand.apply(me, arguments);
- }
- return result;
- };
- });
- /**
- * 删除obj的宽高style,改成属性宽高
- * @param obj
- * @param replaceToProperty
- */
- function removeStyleSize(obj, replaceToProperty) {
- removeStyle(obj, "width", true);
- removeStyle(obj, "height", true);
- }
- function removeStyle(obj, styleName, replaceToProperty) {
- if (obj.style[styleName]) {
- replaceToProperty && obj.setAttribute(styleName, parseInt(obj.style[styleName], 10));
- obj.style[styleName] = "";
- }
- }
- function getParentTdOrTh(ele) {
- if (ele.tagName == "TD" || ele.tagName == "TH") return ele;
- var td;
- if (td = domUtils.findParentByTagName(ele, "td", true) || domUtils.findParentByTagName(ele, "th", true)) return td;
- return null;
- }
- function isEmptyBlock(node) {
- var reg = new RegExp(domUtils.fillChar, 'g');
- if (node[browser.ie ? 'innerText' : 'textContent'].replace(/^\s*$/, '').replace(reg, '').length > 0) {
- return 0;
- }
- for (var n in dtd.$isNotEmpty) {
- if (node.getElementsByTagName(n).length) {
- return 0;
- }
- }
- return 1;
- }
- function mouseCoords(evt) {
- if (evt.pageX || evt.pageY) {
- return { x:evt.pageX, y:evt.pageY };
- }
- return {
- x:evt.clientX + me.document.body.scrollLeft - me.document.body.clientLeft,
- y:evt.clientY + me.document.body.scrollTop - me.document.body.clientTop
- };
- }
- function mouseMoveEvent(evt) {
- try {
- //普通状态下鼠标移动
- var target = getParentTdOrTh(evt.target || evt.srcElement),
- pos;
- //修改单元格大小时的鼠标移动
- if (onDrag && dragTd) {
- me.document.body.style.webkitUserSelect = 'none';
- me.selection.getNative()[browser.ie ? 'empty' : 'removeAllRanges']();
- pos = mouseCoords(evt);
- toggleDragableState(me, true, "", pos, target);
- if (onDrag == "h") {
- dragLine.style.left = getPermissionX(dragTd, evt) + "px";
- } else if (onDrag == "v") {
- dragLine.style.top = getPermissionY(dragTd, evt) + "px";
- }
- return;
- }
- //当鼠标处于table上时,修改移动过程中的光标状态
- if (target) {
- //针对使用table作为容器的组件不触发拖拽效果
- if (me.fireEvent('excludetable', target) === true)
- return;
- pos = mouseCoords(evt);
- var state = getRelation(target, pos),
- table = domUtils.findParentByTagName(target, "table", true);
- if (inTableSide(table, target, evt, true)) {
- //toggleCursor(pos,true,"_h");
- if (me.fireEvent("excludetable", table) === true) return;
- me.body.style.cursor = "url(" + me.options.cursorpath + "h.png),pointer";
- } else if (inTableSide(table, target, evt)) {
- //toggleCursor(pos,true,"_v");
- if (me.fireEvent("excludetable", table) === true) return;
- me.body.style.cursor = "url(" + me.options.cursorpath + "v.png),pointer";
- } else {
- //toggleCursor(pos,false,"");
- me.body.style.cursor = "text";
- if (/\d/.test(state)) {
- state = state.replace(/\d/, '');
- target = getUETable(target).getPreviewCell(target, state == "v");
- }
- //位于第一行的顶部或者第一列的左边时不可拖动
- toggleDragableState(me, target ? !!state : false, target ? state : '', pos, target);
- }
- // toggleDragButton(inTable(pos,table),table);
- } else {
- toggleDragButton(false, table, me);
- }
- } catch (e) {
- showError(e);
- }
- }
- var dragButtomTimer;
- function toggleDragButton(show, table, editor) {
- if (!show) {
- if (dragOver)return;
- dragButtomTimer = setTimeout(function () {
- !dragOver && dragButton && dragButton.parentNode && dragButton.parentNode.removeChild(dragButton);
- }, 2000);
- } else {
- createDragButton(table, editor);
- }
- }
- function createDragButton(table, editor) {
- var pos = domUtils.getXY(table),
- doc = table.ownerDocument;
- if (dragButton && dragButton.parentNode)return dragButton;
- dragButton = doc.createElement("div");
- dragButton.contentEditable = false;
- dragButton.innerHTML = "";
- dragButton.style.cssText = "width:15px;height:15px;background-image:url(" + editor.options.UEDITOR_HOME_URL + "dialogs/table/dragicon.png);position: absolute;cursor:move;top:" + (pos.y - 15) + "px;left:" + (pos.x) + "px;";
- domUtils.unSelectable(dragButton);
- dragButton.onmouseover = function (evt) {
- dragOver = true;
- };
- dragButton.onmouseout = function (evt) {
- dragOver = false;
- };
- domUtils.on(dragButton, 'click', function (type, evt) {
- doClick(evt, this);
- });
- domUtils.on(dragButton, 'dblclick', function (type, evt) {
- doDblClick(evt);
- });
- domUtils.on(dragButton, 'dragstart', function (type, evt) {
- domUtils.preventDefault(evt);
- });
- var timer;
- function doClick(evt, button) {
- // 部分浏览器下需要清理
- clearTimeout(timer);
- timer = setTimeout(function () {
- editor.fireEvent("tableClicked", table, button);
- }, 300);
- }
- function doDblClick(evt) {
- clearTimeout(timer);
- var ut = getUETable(table),
- start = table.rows[0].cells[0],
- end = ut.getLastCell(),
- range = ut.getCellsRange(start, end);
- editor.selection.getRange().setStart(start, 0).setCursor(false, true);
- ut.setSelected(range);
- }
- doc.body.appendChild(dragButton);
- }
- // function inPosition(table, pos) {
- // var tablePos = domUtils.getXY(table),
- // width = table.offsetWidth,
- // height = table.offsetHeight;
- // if (pos.x - tablePos.x < 5 && pos.y - tablePos.y < 5) {
- // return "topLeft";
- // } else if (tablePos.x + width - pos.x < 5 && tablePos.y + height - pos.y < 5) {
- // return "bottomRight";
- // }
- // }
- function inTableSide(table, cell, evt, top) {
- var pos = mouseCoords(evt),
- state = getRelation(cell, pos);
- if (top) {
- var caption = table.getElementsByTagName("caption")[0],
- capHeight = caption ? caption.offsetHeight : 0;
- return (state == "v1") && ((pos.y - domUtils.getXY(table).y - capHeight) < 8);
- } else {
- return (state == "h1") && ((pos.x - domUtils.getXY(table).x) < 8);
- }
- }
- /**
- * 获取拖动时允许的X轴坐标
- * @param dragTd
- * @param evt
- */
- function getPermissionX(dragTd, evt) {
- var ut = getUETable(dragTd);
- if (ut) {
- var preTd = ut.getSameEndPosCells(dragTd, "x")[0],
- nextTd = ut.getSameStartPosXCells(dragTd)[0],
- mouseX = mouseCoords(evt).x,
- left = (preTd ? domUtils.getXY(preTd).x : domUtils.getXY(ut.table).x) + 20 ,
- right = nextTd ? domUtils.getXY(nextTd).x + nextTd.offsetWidth - 20 : (me.body.offsetWidth + 5 || parseInt(domUtils.getComputedStyle(me.body, "width"), 10));
- return mouseX < left ? left : mouseX > right ? right : mouseX;
- }
- }
- /**
- * 获取拖动时允许的Y轴坐标
- * @param dragTd
- * @param evt
- */
- function getPermissionY(dragTd, evt) {
- try {
- var top = domUtils.getXY(dragTd).y,
- mousePosY = mouseCoords(evt).y;
- return mousePosY < top ? top : mousePosY;
- } catch (e) {
- showError(e);
- }
- }
- /**
- * 移动状态切换
- * @param dragable
- * @param dir
- */
- function toggleDragableState(editor, dragable, dir, mousePos, cell) {
- try {
- editor.body.style.cursor = dir == "h" ? "col-resize" : dir == "v" ? "row-resize" : "text";
- if (browser.ie) {
- if (dir && !mousedown && !getUETableBySelected(editor)) {
- getDragLine(editor, editor.document);
- showDragLineAt(dir, cell);
- } else {
- hideDragLine(editor)
- }
- }
- onBorder = dragable;
- } catch (e) {
- showError(e);
- }
- }
- /**
- * 获取鼠标与当前单元格的相对位置
- * @param ele
- * @param mousePos
- */
- function getRelation(ele, mousePos) {
- var elePos = domUtils.getXY(ele);
- if (elePos.x + ele.offsetWidth - mousePos.x < 4) {
- return "h";
- }
- if (mousePos.x - elePos.x < 4) {
- return 'h1'
- }
- if (elePos.y + ele.offsetHeight - mousePos.y < 4) {
- return "v";
- }
- if (mousePos.y - elePos.y < 4) {
- return 'v1'
- }
- return '';
- }
- function mouseDownEvent(type, evt) {
- //右键菜单单独处理
- if (evt.button == 2) {
- var ut = getUETableBySelected(me),
- flag = false;
- if (ut) {
- var td = getTargetTd(me, evt);
- utils.each(ut.selectedTds, function (ti) {
- if (ti === td) {
- flag = true;
- }
- });
- if (!flag) {
- removeSelectedClass(domUtils.getElementsByTagName(me.body, "td"));
- removeSelectedClass(domUtils.getElementsByTagName(me.body, "th"));
- ut.clearSelected()
- } else {
- td = ut.selectedTds[0];
- setTimeout(function () {
- me.selection.getRange().setStart(td, 0).setCursor(false, true);
- }, 0);
- }
- }
- return;
- }
- if (evt.shiftKey) {
- return;
- }
- removeSelectedClass(domUtils.getElementsByTagName(me.body, "td"));
- removeSelectedClass(domUtils.getElementsByTagName(me.body, "th"));
- //trace:3113
- //选中单元格,点击table外部,不会清掉table上挂的ueTable,会引起getUETableBySelected方法返回值
- utils.each(me.document.getElementsByTagName('table'), function (t) {
- t.ueTable = null;
- });
- startTd = getTargetTd(me, evt);
- if (!startTd) return;
- var table = domUtils.findParentByTagName(startTd, "table", true);
- ut = getUETable(table);
- ut && ut.clearSelected();
- //判断当前鼠标状态
- if (!onBorder) {
- me.document.body.style.webkitUserSelect = '';
- mousedown = true;
- me.addListener('mouseover', mouseOverEvent);
- } else {
- if (browser.ie && browser.version < 8) return;
- var state = getRelation(startTd, mouseCoords(evt));
- if (/\d/.test(state)) {
- state = state.replace(/\d/, '');
- startTd = getUETable(startTd).getPreviewCell(startTd, state == 'v');
- }
- hideDragLine(me);
- getDragLine(me, me.document);
- showDragLineAt(state, startTd);
- mousedown = true;
- //拖动开始
- onDrag = state;
- dragTd = startTd;
- }
- }
- function removeSelectedClass(cells) {
- utils.each(cells, function (cell) {
- domUtils.removeClasses(cell, "selectTdClass");
- })
- }
- function addSelectedClass(cells) {
- utils.each(cells, function (cell) {
- domUtils.addClass(cell, "selectTdClass");
- })
- }
- function getWidth(cell) {
- if (!cell)return 0;
- return parseInt(domUtils.getComputedStyle(cell, "width"), 10);
- }
- function changeColWidth(cell, changeValue) {
- if (Math.abs(changeValue) < 10) return;
- var ut = getUETable(cell);
- if (ut) {
- var table = ut.table,
- backTableWidth = getWidth(table),
- defaultValue = getDefaultValue(me, table),
- //这里不考虑一个都没有情况,如果一个都没有,可以认为该表格的结构可以精简
- leftCells = ut.getSameEndPosCells(cell, "x"),
- backLeftWidth = getWidth(leftCells[0]) - defaultValue.tdPadding * 2 - defaultValue.tdBorder,
- rightCells = ut.getSameStartPosXCells(cell),
- backRightWidth = getWidth(rightCells[0]) - defaultValue.tdPadding * 2 - defaultValue.tdBorder;
- //整列被rowspan时存在
- utils.each(leftCells, function (cell) {
- if (cell.style.width) cell.style.width = "";
- if (changeValue < 0)cell.style.wordBreak = "break-all";
- cell.setAttribute("width", backLeftWidth + changeValue);
- });
- utils.each(rightCells, function (cell) {
- if (cell.style.width) cell.style.width = "";
- if (changeValue > 0)cell.style.wordBreak = "break-all";
- cell.setAttribute("width", backRightWidth - changeValue);
- });
- //如果是在表格最右边拖动,则还需要调整表格宽度,否则在合并过的单元格中输入文字,表格会被撑开
- if (!cell.nextSibling) {
- if (table.style.width) table.style.width = "";
- table.setAttribute("width", backTableWidth + changeValue);
- }
- }
- }
- function changeRowHeight(td, changeValue) {
- if (Math.abs(changeValue) < 10) return;
- var ut = getUETable(td);
- if (ut) {
- var cells = ut.getSameEndPosCells(td, "y"),
- //备份需要连带变化的td的原始高度,否则后期无法获取正确的值
- backHeight = cells[0] ? cells[0].offsetHeight : 0;
- for (var i = 0, cell; cell = cells[i++];) {
- setCellHeight(cell, changeValue, backHeight);
- }
- }
- }
- function setCellHeight(cell, height, backHeight) {
- var lineHight = parseInt(domUtils.getComputedStyle(cell, "line-height"), 10),
- tmpHeight = backHeight + height;
- height = tmpHeight < lineHight ? lineHight : tmpHeight;
- if (cell.style.height) cell.style.height = "";
- cell.rowSpan == 1 ? cell.setAttribute("height", height) : (cell.removeAttribute && cell.removeAttribute("height"));
- }
- function mouseUpEvent(type, evt) {
- if (evt.button == 2)return;
- var me = this;
- //清除表格上原生跨选问题
- var range = me.selection.getRange(),
- start = domUtils.findParentByTagName(range.startContainer, 'table', true),
- end = domUtils.findParentByTagName(range.endContainer, 'table', true);
- if (start || end) {
- if (start === end) {
- start = domUtils.findParentByTagName(range.startContainer, ['td', 'th', 'caption'], true);
- end = domUtils.findParentByTagName(range.endContainer, ['td', 'th', 'caption'], true);
- if (start !== end) {
- me.selection.clearRange()
- }
- } else {
- me.selection.clearRange()
- }
- }
- mousedown = false;
- me.document.body.style.webkitUserSelect = '';
- //拖拽状态下的mouseUP
- if ((!browser.ie || (browser.ie && browser.version > 7)) && onDrag && dragTd) {
- dragLine = me.document.getElementById('ue_tableDragLine');
- var dragTdPos = domUtils.getXY(dragTd),
- dragLinePos = domUtils.getXY(dragLine);
- switch (onDrag) {
- case "h":
- changeColWidth(dragTd, dragLinePos.x - dragTdPos.x - dragTd.offsetWidth);
- break;
- case "v":
- changeRowHeight(dragTd, dragLinePos.y - dragTdPos.y - dragTd.offsetHeight);
- break;
- default:
- }
- onDrag = "";
- dragTd = null;
- hideDragLine(me);
- return;
- }
- //正常状态下的mouseup
- if (!startTd) {
- var target = domUtils.findParentByTagName(evt.target || evt.srcElement, "td", true);
- if (!target) target = domUtils.findParentByTagName(evt.target || evt.srcElement, "th", true);
- if (target && (target.tagName == "TD" || target.tagName == "TH")) {
- if (me.fireEvent("excludetable", target) === true) return;
- range = new dom.Range(me.document);
- range.setStart(target, 0).setCursor(false, true);
- }
- } else {
- var ut = getUETable(startTd),
- cell = ut ? ut.selectedTds[0] : null;
- if (cell) {
- range = new dom.Range(me.document);
- if (domUtils.isEmptyBlock(cell)) {
- range.setStart(cell, 0).setCursor(false, true);
- } else {
- range.selectNodeContents(cell).shrinkBoundary().setCursor(false, true);
- }
- } else {
- range = me.selection.getRange().shrinkBoundary();
- if (!range.collapsed) {
- var start = domUtils.findParentByTagName(range.startContainer, ['td', 'th'], true),
- end = domUtils.findParentByTagName(range.endContainer, ['td', 'th'], true);
- //在table里边的不能清除
- if (start && !end || !start && end || start && end && start !== end) {
- range.setCursor(false, true);
- }
- }
- }
- startTd = null;
- me.removeListener('mouseover', mouseOverEvent);
- }
- me._selectionChange(250, evt);
- }
- function mouseOverEvent(type, evt) {
- var me = this,
- tar = evt.target || evt.srcElement;
- currentTd = domUtils.findParentByTagName(tar, "td", true) || domUtils.findParentByTagName(tar, "th", true);
- //需要判断两个TD是否位于同一个表格内
- if (startTd && currentTd &&
- ((startTd.tagName == "TD" && currentTd.tagName == "TD") || (startTd.tagName == "TH" && currentTd.tagName == "TH")) &&
- domUtils.findParentByTagName(startTd, 'table') == domUtils.findParentByTagName(currentTd, 'table')) {
- var ut = getUETable(currentTd);
- if (startTd != currentTd) {
- me.document.body.style.webkitUserSelect = 'none';
- me.selection.getNative()[browser.ie ? 'empty' : 'removeAllRanges']();
- var range = ut.getCellsRange(startTd, currentTd);
- ut.setSelected(range);
- } else {
- me.document.body.style.webkitUserSelect = '';
- ut.clearSelected();
- }
- }
- evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);
- }
- /**
- * 根据当前点击的td或者table获取索引对象
- * @param tdOrTable
- */
- function getUETable(tdOrTable) {
- var tag = tdOrTable.tagName.toLowerCase();
- tdOrTable = (tag == "td" || tag == "th" || tag == 'caption') ? domUtils.findParentByTagName(tdOrTable, "table", true) : tdOrTable;
- if (!tdOrTable.ueTable) {
- tdOrTable.ueTable = new UETable(tdOrTable);
- }
- return tdOrTable.ueTable;
- }
- /**
- * 根据当前框选的td来获取ueTable对象
- */
- function getUETableBySelected(editor) {
- var table = getTableItemsByRange(editor).table;
- if (table && table.ueTable && table.ueTable.selectedTds.length) {
- return table.ueTable;
- }
- return null;
- }
- function getDragLine(editor, doc) {
- if (mousedown)return;
- dragLine = editor.document.createElement("div");
- domUtils.setAttributes(dragLine, {
- id:"ue_tableDragLine",
- unselectable:'on',
- contenteditable:false,
- 'onresizestart':'return false',
- 'ondragstart':'return false',
- 'onselectstart':'return false',
- style:"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)"
- });
- // domUtils.on(dragLine,['resizestart','dragstart','selectstart'],function(evt){
- // domUtils.preventDefault(evt);
- // });
- editor.body.appendChild(dragLine);
- }
- function hideDragLine(editor) {
- if (mousedown)return;
- var line;
- while (line = editor.document.getElementById('ue_tableDragLine')) {
- domUtils.remove(line)
- }
- }
- /**
- * 依据state(v|h)在cell位置显示横线
- * @param state
- * @param cell
- */
- function showDragLineAt(state, cell) {
- if (!cell) return;
- var table = domUtils.findParentByTagName(cell, "table"),
- caption = table.getElementsByTagName('caption'),
- width = table.offsetWidth,
- height = table.offsetHeight - (caption.length > 0 ? caption[0].offsetHeight : 0),
- tablePos = domUtils.getXY(table),
- cellPos = domUtils.getXY(cell), css;
- switch (state) {
- case "h":
- css = 'height:' + height + 'px;top:' + (tablePos.y + (caption.length > 0 ? caption[0].offsetHeight : 0)) + 'px;left:' + (cellPos.x + cell.offsetWidth - 2);
- dragLine.style.cssText = css + 'px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)';
- break;
- case "v":
- css = 'width:' + width + 'px;left:' + tablePos.x + 'px;top:' + (cellPos.y + cell.offsetHeight - 2 );
- //必须加上border:0和color:blue,否则低版ie不支持背景色显示
- dragLine.style.cssText = css + 'px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)';
- break;
- default:
- }
- }
- /**
- * 当表格边框颜色为白色时设置为虚线,true为添加虚线
- * @param flag
- */
- function switchBoderColor(flag) {
- var tableArr = domUtils.getElementsByTagName(me.body, "table"), color;
- for (var i = 0, node; node = tableArr[i++];) {
- var td = domUtils.getElementsByTagName(node, "td");
- if (td[0]) {
- if (flag) {
- color = (td[0].style.borderColor).replace(/\s/g, "");
- if (/(#ffffff)|(rgb\(255,f55,255\))/ig.test(color))
- domUtils.addClass(node, "noBorderTable")
- } else {
- domUtils.removeClasses(node, "noBorderTable")
- }
- }
- }
- }
- function getTableWidth(editor, needIEHack, defaultValue) {
- var body = editor.body;
- return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0);
- }
- UE.commands['inserttable'] = {
- queryCommandState:function () {
- return getTableItemsByRange(this).table ? -1 : 0;
- },
- execCommand:function (cmd, opt) {
- function createTable(opt, tableWidth, tdWidth) {
- var html = [],
- rowsNum = opt.numRows,
- colsNum = opt.numCols;
- for (var r = 0; r < rowsNum; r++) {
- html.push('<tr>');
- for (var c = 0; c < colsNum; c++) {
- html.push('<td width="' + tdWidth + '" vAlign="' + opt.tdvalign + '" >' + (browser.ie ? domUtils.fillChar : '<br/>') + '</td>')
- }
- html.push('</tr>')
- }
- return '<table width="' + tableWidth + '" ><tbody>' + html.join('') + '</tbody></table>'
- }
- if (!opt) {
- opt = utils.extend({}, {
- numCols:this.options.defaultCols,
- numRows:this.options.defaultRows,
- tdvalign:this.options.tdvalign
- })
- }
- var range = this.selection.getRange(),
- start = range.startContainer,
- firstParentBlock = domUtils.findParent(start, function (node) {
- return domUtils.isBlockElm(node);
- }, true);
- var me = this,
- defaultValue = getDefaultValue(me),
- tableWidth = getTableWidth(me, needIEHack, defaultValue) - (firstParentBlock ? parseInt(domUtils.getXY(firstParentBlock).x, 10) : 0),
- tdWidth = Math.floor(tableWidth / opt.numCols - defaultValue.tdPadding * 2 - defaultValue.tdBorder);
- //todo其他属性
- !opt.tdvalign && (opt.tdvalign = me.options.tdvalign);
- me.execCommand("inserthtml", createTable(opt, tableWidth, tdWidth));
- }
- };
- UE.commands['insertparagraphbeforetable'] = {
- queryCommandState:function () {
- return getTableItemsByRange(this).cell ? 0 : -1;
- },
- execCommand:function () {
- var table = getTableItemsByRange(this).table;
- if (table) {
- var p = this.document.createElement("p");
- p.innerHTML = browser.ie ? ' ' : '<br />';
- table.parentNode.insertBefore(p, table);
- this.selection.getRange().setStart(p, 0).setCursor();
- }
- }
- };
- UE.commands['deletetable'] = {
- queryCommandState:function () {
- var rng = this.selection.getRange();
- return domUtils.findParentByTagName(rng.startContainer, 'table', true) ? 0 : -1;
- },
- execCommand:function (cmd, table) {
- var rng = this.selection.getRange();
- table = table || domUtils.findParentByTagName(rng.startContainer, 'table', true);
- if (table) {
- var next = table.nextSibling;
- if (!next) {
- next = domUtils.createElement(this.document, 'p', {
- 'innerHTML':browser.ie ? domUtils.fillChar : '<br/>'
- });
- table.parentNode.insertBefore(next, table);
- }
- domUtils.remove(table);
- rng = this.selection.getRange();
- if (next.nodeType == 3) {
- rng.setStartBefore(next)
- } else {
- rng.setStart(next, 0)
- }
- rng.setCursor(false, true)
- toggleDragableState(this, false, "", null);
- if (dragButton)domUtils.remove(dragButton);
- }
- }
- };
-
- UE.commands['signset'] = {
- execCommand : function(){
- var imgs = this.document.getElementsByTagName("img");
- for(var i= 0,img;img = imgs[i++];){
- img.setAttribute("border",2);
- img.setAttribute("width","100");
- img.setAttribute("height","100");
- }
- },
- queryCommandState:function(){
- var images = this.document.getElementsByTagName("img" );
- for(var i=0;i<$(images).length;i++){
- if($(images[i]).css("width")!="100px"){
- return 0; //如果找到宽度不为100的图片,则返回0,代表当前按钮可以点击
- }
- }
- return -1; //否则返回-1,告诉编辑器将当前按钮置灰
- }
- };
-
- UE.commands['cellalign'] = {
- queryCommandState:function () {
- return getSelectedArr(this).length ? 0 : -1
- },
- execCommand:function (cmd, align) {
- var selectedTds = getSelectedArr(this);
- if (selectedTds.length) {
- for (var i = 0, ci; ci = selectedTds[i++];) {
- ci.setAttribute('align', align);
- }
- }
- }
- };
- UE.commands['cellvalign'] = {
- queryCommandState:function () {
- return getSelectedArr(this).length ? 0 : -1;
- },
- execCommand:function (cmd, valign) {
- var selectedTds = getSelectedArr(this);
- if (selectedTds.length) {
- for (var i = 0, ci; ci = selectedTds[i++];) {
- ci.setAttribute('vAlign', valign);
- }
- }
- }
- };
- UE.commands['insertcaption'] = {
- queryCommandState:function () {
- var table = getTableItemsByRange(this).table;
- if (table) {
- return table.getElementsByTagName('caption').length == 0 ? 1 : -1;
- }
- return -1;
- },
- execCommand:function () {
- var table = getTableItemsByRange(this).table;
- if (table) {
- var caption = this.document.createElement('caption');
- caption.innerHTML = browser.ie ? domUtils.fillChar : '<br/>';
- table.insertBefore(caption, table.firstChild);
- var range = this.selection.getRange();
- range.setStart(caption, 0).setCursor();
- }
- }
- };
- UE.commands['deletecaption'] = {
- queryCommandState:function () {
- var rng = this.selection.getRange(),
- table = domUtils.findParentByTagName(rng.startContainer, 'table');
- if (table) {
- return table.getElementsByTagName('caption').length == 0 ? -1 : 1;
- }
- return -1;
- },
- execCommand:function () {
- var rng = this.selection.getRange(),
- table = domUtils.findParentByTagName(rng.startContainer, 'table');
- if (table) {
- domUtils.remove(table.getElementsByTagName('caption')[0]);
- var range = this.selection.getRange();
- range.setStart(table.rows[0].cells[0], 0).setCursor();
- }
- }
- };
- UE.commands['inserttitle'] = {
- queryCommandState:function () {
- var table = getTableItemsByRange(this).table;
- if (table) {
- var firstRow = table.rows[0];
- return firstRow.getElementsByTagName('th').length == 0 ? 0 : -1
- }
- return -1;
- },
- execCommand:function () {
- var table = getTableItemsByRange(this).table;
- if (table) {
- getUETable(table).insertRow(0, 'th');
- }
- var th = table.getElementsByTagName('th')[0];
- this.selection.getRange().setStart(th, 0).setCursor(false, true);
- }
- };
- UE.commands['deletetitle'] = {
- queryCommandState:function () {
- var table = getTableItemsByRange(this).table;
- if (table) {
- var firstRow = table.rows[0];
- return firstRow.getElementsByTagName('th').length ? 0 : -1
- }
- return -1;
- },
- execCommand:function () {
- var table = getTableItemsByRange(this).table;
- if (table) {
- domUtils.remove(table.rows[0])
- }
- var td = table.getElementsByTagName('td')[0];
- this.selection.getRange().setStart(td, 0).setCursor(false, true);
- }
- };
-
- UE.commands["mergeright"] = {
- queryCommandState:function (cmd) {
- var tableItems = getTableItemsByRange(this);
- if (!tableItems.cell) return -1;
- var ut = getUETable(tableItems.table);
- if (ut.selectedTds.length) return -1;
- var cellInfo = ut.getCellInfo(tableItems.cell),
- rightColIndex = cellInfo.colIndex + cellInfo.colSpan;
- if (rightColIndex >= ut.colsNum) return -1;
- var rightCellInfo = ut.indexTable[cellInfo.rowIndex][rightColIndex];
- return (rightCellInfo.rowIndex == cellInfo.rowIndex
- && rightCellInfo.rowSpan == cellInfo.rowSpan) ? 0 : -1;
- },
- execCommand:function (cmd) {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell);
- ut.mergeRight(cell);
- rng.moveToBookmark(bk).select();
- }
- };
- UE.commands["mergedown"] = {
- queryCommandState:function (cmd) {
- var tableItems = getTableItemsByRange(this),
- cell = tableItems.cell;
- if (!cell || cell.tagName == "TH") return -1;
- var ut = getUETable(tableItems.table);
- if (ut.selectedTds.length)return -1;
- var cellInfo = ut.getCellInfo(tableItems.cell),
- downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan;
- // 如果处于最下边则不能f向右合并
- if (downRowIndex >= ut.rowsNum) return -1;
- var downCellInfo = ut.indexTable[downRowIndex][cellInfo.colIndex];
- // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并
- return (downCellInfo.colIndex == cellInfo.colIndex
- && downCellInfo.colSpan == cellInfo.colSpan) && tableItems.cell.tagName !== 'TH' ? 0 : -1;
- },
- execCommand:function () {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell);
- ut.mergeDown(cell);
- rng.moveToBookmark(bk).select();
- }
- };
- UE.commands["mergecells"] = {
- queryCommandState:function () {
- return getUETableBySelected(this) ? 0 : -1;
- },
- execCommand:function () {
- var ut = getUETableBySelected(this);
- if (ut && ut.selectedTds.length) {
- var cell = ut.selectedTds[0];
- getUETableBySelected(this).mergeRange();
- var rng = this.selection.getRange();
- if (domUtils.isEmptyBlock(cell)) {
- rng.setStart(cell, 0).collapse(true)
- } else {
- rng.selectNodeContents(cell)
- }
- rng.select();
- }
- }
- };
- UE.commands["insertrow"] = {
- queryCommandState:function () {
- var tableItems = getTableItemsByRange(this),
- cell = tableItems.cell;
- return cell && cell.tagName == "TD" && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1;
- },
- execCommand:function () {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell),
- cellInfo = ut.getCellInfo(cell);
- //ut.insertRow(!ut.selectedTds.length ? cellInfo.rowIndex:ut.cellsRange.beginRowIndex,'');
- if (!ut.selectedTds.length) {
- ut.insertRow(cellInfo.rowIndex, cell);
- } else {
- var range = ut.cellsRange;
- for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) {
- ut.insertRow(range.beginRowIndex, cell);
- }
- }
- rng.moveToBookmark(bk).select();
- }
- };
- //后插入行
- UE.commands["insertrownext"] = {
- queryCommandState:function () {
- var tableItems = getTableItemsByRange(this),
- cell = tableItems.cell;
- return cell && (cell.tagName == "TD") && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1;
- },
- execCommand:function () {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell),
- cellInfo = ut.getCellInfo(cell);
- //ut.insertRow(!ut.selectedTds.length? cellInfo.rowIndex + cellInfo.rowSpan : ut.cellsRange.endRowIndex + 1,'');
- if (!ut.selectedTds.length) {
- ut.insertRow(cellInfo.rowIndex + cellInfo.rowSpan, cell);
- } else {
- var range = ut.cellsRange;
- for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) {
- ut.insertRow(range.endRowIndex + 1, cell);
- }
- }
- rng.moveToBookmark(bk).select();
- }
- };
- UE.commands["deleterow"] = {
- queryCommandState:function () {
- var tableItems = getTableItemsByRange(this);
- if (!tableItems.cell) {
- return -1;
- }
- },
- execCommand:function () {
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell),
- cellsRange = ut.cellsRange,
- cellInfo = ut.getCellInfo(cell),
- preCell = ut.getVSideCell(cell),
- nextCell = ut.getVSideCell(cell, true),
- rng = this.selection.getRange();
- if (utils.isEmptyObject(cellsRange)) {
- ut.deleteRow(cellInfo.rowIndex);
- } else {
- for (var i = cellsRange.beginRowIndex; i < cellsRange.endRowIndex + 1; i++) {
- ut.deleteRow(cellsRange.beginRowIndex);
- }
- }
- var table = ut.table;
- if (!table.getElementsByTagName('td').length) {
- var nextSibling = table.nextSibling;
- domUtils.remove(table);
- if (nextSibling) {
- rng.setStart(nextSibling, 0).setCursor(false, true);
- }
- } else {
- if (cellInfo.rowSpan == 1 || cellInfo.rowSpan == cellsRange.endRowIndex - cellsRange.beginRowIndex + 1) {
- if (nextCell || preCell) rng.selectNodeContents(nextCell || preCell).setCursor(false, true);
- } else {
- var newCell = ut.getCell(cellInfo.rowIndex, ut.indexTable[cellInfo.rowIndex][cellInfo.colIndex].cellIndex);
- if (newCell) rng.selectNodeContents(newCell).setCursor(false, true);
- }
- }
- }
- };
- UE.commands["insertcol"] = {
- queryCommandState:function (cmd) {
- var tableItems = getTableItemsByRange(this),
- cell = tableItems.cell;
- return cell && (cell.tagName == "TD" || cell.tagName == 'TH') && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1;
- },
- execCommand:function (cmd) {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- if (this.queryCommandState(cmd) == -1)return;
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell),
- cellInfo = ut.getCellInfo(cell);
- //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex:ut.cellsRange.beginColIndex);
- if (!ut.selectedTds.length) {
- ut.insertCol(cellInfo.colIndex, cell);
- } else {
- var range = ut.cellsRange;
- for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) {
- ut.insertCol(range.beginColIndex, cell);
- }
- }
- rng.moveToBookmark(bk).select(true);
- }
- };
- UE.commands["insertcolnext"] = {
- queryCommandState:function () {
- var tableItems = getTableItemsByRange(this),
- cell = tableItems.cell;
- return cell && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1;
- },
- execCommand:function () {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell),
- cellInfo = ut.getCellInfo(cell);
- //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex + cellInfo.colSpan:ut.cellsRange.endColIndex +1);
- if (!ut.selectedTds.length) {
- ut.insertCol(cellInfo.colIndex + cellInfo.colSpan, cell);
- } else {
- var range = ut.cellsRange;
- for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) {
- ut.insertCol(range.endColIndex + 1, cell);
- }
- }
- rng.moveToBookmark(bk).select();
- }
- };
- UE.commands["deletecol"] = {
- queryCommandState:function () {
- var tableItems = getTableItemsByRange(this);
- if (!tableItems.cell) return -1;
- },
- execCommand:function () {
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell),
- range = ut.cellsRange,
- cellInfo = ut.getCellInfo(cell),
- preCell = ut.getHSideCell(cell),
- nextCell = ut.getHSideCell(cell, true);
- if (utils.isEmptyObject(range)) {
- ut.deleteCol(cellInfo.colIndex);
- } else {
- for (var i = range.beginColIndex; i < range.endColIndex + 1; i++) {
- ut.deleteCol(range.beginColIndex);
- }
- }
- var table = ut.table,
- rng = this.selection.getRange();
- if (!table.getElementsByTagName('td').length) {
- var nextSibling = table.nextSibling;
- domUtils.remove(table);
- if (nextSibling) {
- rng.setStart(nextSibling, 0).setCursor(false, true);
- }
- } else {
- if (domUtils.inDoc(cell, this.document)) {
- rng.setStart(cell, 0).setCursor(false, true);
- } else {
- if (nextCell && domUtils.inDoc(nextCell, this.document)) {
- rng.selectNodeContents(nextCell).setCursor(false, true);
- } else {
- if (preCell && domUtils.inDoc(preCell, this.document)) {
- rng.selectNodeContents(preCell).setCursor(true, true);
- }
- }
- }
- }
- }
- };
- UE.commands["splittocells"] = {
- queryCommandState:function () {
- var tableItems = getTableItemsByRange(this),
- cell = tableItems.cell;
- if (!cell) return -1;
- var ut = getUETable(tableItems.table);
- if (ut.selectedTds.length > 0) return -1;
- return cell && (cell.colSpan > 1 || cell.rowSpan > 1) ? 0 : -1;
- },
- execCommand:function () {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell);
- ut.splitToCells(cell);
- rng.moveToBookmark(bk).select();
- }
- };
- UE.commands["splittorows"] = {
- queryCommandState:function () {
- var tableItems = getTableItemsByRange(this),
- cell = tableItems.cell;
- if (!cell) return -1;
- var ut = getUETable(tableItems.table);
- if (ut.selectedTds.length > 0) return -1;
- return cell && cell.rowSpan > 1 ? 0 : -1;
- },
- execCommand:function () {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell);
- ut.splitToRows(cell);
- rng.moveToBookmark(bk).select();
- }
- };
- UE.commands["splittocols"] = {
- queryCommandState:function () {
- var tableItems = getTableItemsByRange(this),
- cell = tableItems.cell;
- if (!cell) return -1;
- var ut = getUETable(tableItems.table);
- if (ut.selectedTds.length > 0) return -1;
- return cell && cell.colSpan > 1 ? 0 : -1;
- },
- execCommand:function () {
- var rng = this.selection.getRange(),
- bk = rng.createBookmark(true);
- var cell = getTableItemsByRange(this).cell,
- ut = getUETable(cell);
- ut.splitToCols(cell);
- rng.moveToBookmark(bk).select();
- }
- };
- function getDefaultValue(editor, table) {
- var borderMap = {
- thin:'0px',
- medium:'1px',
- thick:'2px'
- },
- tableBorder, tdPadding, tdBorder, tmpValue;
- if (!table) {
- table = editor.document.createElement('table');
- table.insertRow(0).insertCell(0).innerHTML = 'xxx';
- editor.body.appendChild(table);
- var td = table.getElementsByTagName('td')[0];
- tmpValue = domUtils.getComputedStyle(table, 'border-left-width');
- tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);
- tmpValue = domUtils.getComputedStyle(td, 'padding-left');
- tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10);
- tmpValue = domUtils.getComputedStyle(td, 'border-left-width');
- tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);
- domUtils.remove(table);
- return {
- tableBorder:tableBorder,
- tdPadding:tdPadding,
- tdBorder:tdBorder
- };
- } else {
- td = table.getElementsByTagName('td')[0];
- tmpValue = domUtils.getComputedStyle(table, 'border-left-width');
- tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);
- tmpValue = domUtils.getComputedStyle(td, 'padding-left');
- tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10);
- tmpValue = domUtils.getComputedStyle(td, 'border-left-width');
- tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);
- return {
- tableBorder:tableBorder,
- tdPadding:tdPadding,
- tdBorder:tdBorder
- };
- }
- }
- UE.commands["adaptbytext"] =
- UE.commands["adaptbywindow"] = {
- queryCommandState:function () {
- return getTableItemsByRange(this).table ? 0 : -1
- },
- execCommand:function (cmd) {
- var tableItems = getTableItemsByRange(this),
- table = tableItems.table;
- if (table) {
- var tds = table.getElementsByTagName("td");
- utils.each(tds, function (td) {
- td.removeAttribute("width");
- });
- if (cmd == 'adaptbywindow') {
- table.setAttribute('width', getTableWidth(this, needIEHack, getDefaultValue(this, table)));
- utils.each(tds, function (td) {
- td.setAttribute("width", td.offsetWidth + "");
- });
- } else {
- table.style.width = "";
- table.removeAttribute("width");
- var defaultValue = getDefaultValue(me, table);
- var width = table.offsetWidth,
- bodyWidth = me.body.offsetWidth;
- if (width > bodyWidth) {
- table.setAttribute('width', getTableWidth(me, needIEHack, defaultValue));
- }
- }
- }
- }
- };
- //平均分配各列
- UE.commands['averagedistributecol'] = {
- queryCommandState:function () {
- var ut = getUETableBySelected(this);
- if (!ut) return -1;
- return ut.isFullRow() || ut.isFullCol() ? 0 : -1;
- },
- execCommand:function (cmd) {
- var me = this,
- ut = getUETableBySelected(me);
- function getAverageWidth() {
- var tb = ut.table,
- averageWidth, sumWidth = 0, colsNum = 0,
- tbAttr = getDefaultValue(me, tb);
- if (ut.isFullRow()) {
- sumWidth = tb.offsetWidth;
- colsNum = ut.colsNum;
- } else {
- var begin = ut.cellsRange.beginColIndex,
- end = ut.cellsRange.endColIndex,
- node;
- for (var i = begin; i <= end;) {
- node = ut.selectedTds[i];
- sumWidth += node.offsetWidth;
- i += node.colSpan;
- colsNum += 1;
- }
- }
- averageWidth = Math.ceil(sumWidth / colsNum) - tbAttr.tdBorder * 2 - tbAttr.tdPadding * 2;
- return averageWidth;
- }
- function setAverageWidth(averageWidth) {
- utils.each(domUtils.getElementsByTagName(ut.table, "th"), function (node) {
- node.setAttribute("width", "");
- });
- var cells = ut.isFullRow() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds;
- utils.each(cells, function (node) {
- if (node.colSpan == 1) {
- node.setAttribute("width", averageWidth);
- }
- });
- }
- if (ut && ut.selectedTds.length) {
- setAverageWidth(getAverageWidth());
- }
- }
- };
- //平均分配各行
- UE.commands['averagedistributerow'] = {
- queryCommandState:function () {
- var ut = getUETableBySelected(this);
- if (!ut) return -1;
- if (ut.selectedTds && /th/ig.test(ut.selectedTds[0].tagName)) return -1;
- return ut.isFullRow() || ut.isFullCol() ? 0 : -1;
- },
- execCommand:function (cmd) {
- var me = this,
- ut = getUETableBySelected(me);
- function getAverageHeight() {
- var averageHeight, rowNum, sumHeight = 0,
- tb = ut.table,
- tbAttr = getDefaultValue(me, tb),
- tdpadding = parseInt(domUtils.getComputedStyle(tb.getElementsByTagName('td')[0], "padding-top"));
- if (ut.isFullCol()) {
- var captionArr = domUtils.getElementsByTagName(tb, "caption"),
- thArr = domUtils.getElementsByTagName(tb, "th"),
- captionHeight, thHeight;
- if (captionArr.length > 0) {
- captionHeight = captionArr[0].offsetHeight;
- }
- if (thArr.length > 0) {
- thHeight = thArr[0].offsetHeight;
- }
- sumHeight = tb.offsetHeight - (captionHeight || 0) - (thHeight || 0);
- rowNum = thArr.length == 0 ? ut.rowsNum : (ut.rowsNum - 1);
- } else {
- var begin = ut.cellsRange.beginRowIndex,
- end = ut.cellsRange.endRowIndex,
- count = 0,
- trs = domUtils.getElementsByTagName(tb, "tr");
- for (var i = begin; i <= end; i++) {
- sumHeight += trs[i].offsetHeight;
- count += 1;
- }
- rowNum = count;
- }
- //ie8下是混杂模式
- if (browser.ie && browser.version < 9) {
- averageHeight = Math.ceil(sumHeight / rowNum);
- } else {
- averageHeight = Math.ceil(sumHeight / rowNum) - tbAttr.tdBorder * 2 - tdpadding * 2;
- }
- return averageHeight;
- }
- function setAverageHeight(averageHeight) {
- var cells = ut.isFullCol() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds;
- utils.each(cells, function (node) {
- if (node.rowSpan == 1) {
- node.setAttribute("height", averageHeight);
- }
- });
- }
- if (ut && ut.selectedTds.length) {
- setAverageHeight(getAverageHeight());
- }
- }
- };
- //单元格对齐方式
- UE.commands['cellalignment'] = {
- queryCommandState:function () {
- return getTableItemsByRange(this).table ? 0 : -1
- },
- execCommand:function (cmd, data) {
- var me = this,
- ut = getUETableBySelected(me);
- if (!ut) {
- var start = me.selection.getStart(),
- cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true);
- if (!/caption/ig.test(cell.tagName)) {
- domUtils.setAttributes(cell, data);
- } else {
- cell.style.textAlign = data.align;
- cell.style.verticalAlign = data.vAlign;
- }
- me.selection.getRange().setCursor(true);
- } else {
- utils.each(ut.selectedTds, function (cell) {
- domUtils.setAttributes(cell, data);
- });
- }
- }
- };
- //表格对齐方式
- UE.commands['tablealignment'] = {
- queryCommandState:function () {
- return getTableItemsByRange(this).table ? 0 : -1
- },
- execCommand:function (cmd, data) {
- var me = this,
- start = me.selection.getStart(),
- table = start && domUtils.findParentByTagName(start, ["table"], true);
- if (table) {
- var obj = {};
- obj[data[0]] = data[1];
- table.style[utils.cssStyleToDomStyle("float")] = "";
- table.style.margin = "";
- domUtils.setStyles(table, obj);
- }
- }
- };
- //表格属性
- UE.commands['edittable'] = {
- queryCommandState:function () {
- return getTableItemsByRange(this).table ? 0 : -1
- },
- execCommand:function (cmd, color) {
- var rng = this.selection.getRange(),
- table = domUtils.findParentByTagName(rng.startContainer, 'table');
- if (table) {
- var arr = domUtils.getElementsByTagName(table, "td").concat(
- domUtils.getElementsByTagName(table, "th"),
- domUtils.getElementsByTagName(table, "caption")
- );
- utils.each(arr, function (node) {
- node.style.borderColor = color;
- });
- }
- }
- };
- //单元格属性
- UE.commands['edittd'] = {
- queryCommandState:function () {
- return getTableItemsByRange(this).table ? 0 : -1
- },
- execCommand:function (cmd, bkColor) {
- var me = this,
- ut = getUETableBySelected(me);
- if (!ut) {
- var start = me.selection.getStart(),
- cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true);
- if (cell) {
- cell.style.backgroundColor = bkColor;
- }
- } else {
- utils.each(ut.selectedTds, function (cell) {
- cell.style.backgroundColor = bkColor;
- });
- }
- }
- };
- /**
- * UE表格操作类
- * @param table
- * @constructor
- */
- function UETable(table) {
- this.table = table;
- this.indexTable = [];
- this.selectedTds = [];
- this.cellsRange = {};
- this.update(table);
- }
- UETable.prototype = {
- getMaxRows:function () {
- var rows = this.table.rows, maxLen = 1;
- for (var i = 0, row; row = rows[i]; i++) {
- var currentMax = 1;
- for (var j = 0, cj; cj = row.cells[j++];) {
- currentMax = Math.max(cj.rowSpan || 1, currentMax);
- }
- maxLen = Math.max(currentMax + i, maxLen);
- }
- return maxLen;
- },
- /**
- * 获取当前表格的最大列数
- */
- getMaxCols:function () {
- var rows = this.table.rows, maxLen = 0, cellRows = {};
- for (var i = 0, row; row = rows[i]; i++) {
- var cellsNum = 0;
- for (var j = 0, cj; cj = row.cells[j++];) {
- cellsNum += (cj.colSpan || 1);
- if (cj.rowSpan && cj.rowSpan > 1) {
- for (var k = 1; k < cj.rowSpan; k++) {
- if (!cellRows['row_' + (i + k)]) {
- cellRows['row_' + (i + k)] = (cj.colSpan || 1);
- } else {
- cellRows['row_' + (i + k)]++
- }
- }
- }
- }
- cellsNum += cellRows['row_' + i] || 0;
- maxLen = Math.max(cellsNum, maxLen);
- }
- return maxLen;
- },
- getCellColIndex:function (cell) {
- },
- /**
- * 获取当前cell旁边的单元格,
- * @param cell
- * @param right
- */
- getHSideCell:function (cell, right) {
- try {
- var cellInfo = this.getCellInfo(cell),
- previewRowIndex, previewColIndex;
- var len = this.selectedTds.length,
- range = this.cellsRange;
- //首行或者首列没有前置单元格
- if ((!right && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (right && (!len ? (cellInfo.colIndex == (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null;
- previewRowIndex = !len ? cellInfo.rowIndex : range.beginRowIndex;
- previewColIndex = !right ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1)
- : ( !len ? cellInfo.colIndex + 1 : range.endColIndex + 1);
- return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex);
- } catch (e) {
- showError(e);
- }
- },
- getTabNextCell:function (cell, preRowIndex) {
- var cellInfo = this.getCellInfo(cell),
- rowIndex = preRowIndex || cellInfo.rowIndex,
- colIndex = cellInfo.colIndex + 1 + (cellInfo.colSpan - 1),
- nextCell;
- try {
- nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex);
- } catch (e) {
- try {
- rowIndex = rowIndex * 1 + 1;
- colIndex = 0;
- nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex);
- } catch (e) {
- }
- }
- return nextCell;
- },
- /**
- * 获取视觉上的后置单元格
- * @param cell
- * @param bottom
- */
- getVSideCell:function (cell, bottom, ignoreRange) {
- try {
- var cellInfo = this.getCellInfo(cell),
- nextRowIndex, nextColIndex;
- var len = this.selectedTds.length && !ignoreRange,
- range = this.cellsRange;
- //末行或者末列没有后置单元格
- if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null;
- nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1)
- : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1);
- nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex;
- return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex);
- } catch (e) {
- showError(e);
- }
- },
- /**
- * 获取相同结束位置的单元格,xOrY指代了是获取x轴相同还是y轴相同
- */
- getSameEndPosCells:function (cell, xOrY) {
- try {
- var flag = (xOrY.toLowerCase() === "x"),
- end = domUtils.getXY(cell)[flag ? 'x' : 'y'] + cell["offset" + (flag ? 'Width' : 'Height')],
- rows = this.table.rows,
- cells = null, returns = [];
- for (var i = 0; i < this.rowsNum; i++) {
- cells = rows[i].cells;
- for (var j = 0, tmpCell; tmpCell = cells[j++];) {
- var tmpEnd = domUtils.getXY(tmpCell)[flag ? 'x' : 'y'] + tmpCell["offset" + (flag ? 'Width' : 'Height')];
- //对应行的td已经被上面行rowSpan了
- if (tmpEnd > end && flag) break;
- if (cell == tmpCell || end == tmpEnd) {
- //只获取单一的单元格
- //todo 仅获取单一单元格在特定情况下会造成returns为空,从而影响后续的拖拽实现,修正这个。需考虑性能
- if (tmpCell[flag ? "colSpan" : "rowSpan"] == 1) {
- returns.push(tmpCell);
- }
- if (flag) break;
- }
- }
- }
- return returns;
- } catch (e) {
- showError(e);
- }
- },
- setCellContent:function (cell, content) {
- cell.innerHTML = content || (browser.ie ? domUtils.fillChar : "<br />");
- },
- cloneCell:cloneCell,
- /**
- * 获取跟当前单元格的右边竖线为左边的所有未合并单元格
- */
- getSameStartPosXCells:function (cell) {
- try {
- var start = domUtils.getXY(cell).x + cell.offsetWidth,
- rows = this.table.rows, cells , returns = [];
- for (var i = 0; i < this.rowsNum; i++) {
- cells = rows[i].cells;
- for (var j = 0, tmpCell; tmpCell = cells[j++];) {
- var tmpStart = domUtils.getXY(tmpCell).x;
- if (tmpStart > start) break;
- if (tmpStart == start && tmpCell.colSpan == 1) {
- returns.push(tmpCell);
- break;
- }
- }
- }
- return returns;
- } catch (e) {
- showError(e);
- }
- },
- /**
- * 更新table对应的索引表
- */
- update:function (table) {
- this.table = table || this.table;
- this.selectedTds = [];
- this.cellsRange = {};
- this.indexTable = [];
- var rows = this.table.rows,
- //暂时采用rows Length,对残缺表格可能存在问题,
- //todo 可以考虑取最大值
- rowsNum = rows.length,
- colsNum = this.getMaxCols();
- this.rowsNum = rowsNum;
- this.colsNum = colsNum;
- for (var i = 0, len = rows.length; i < len; i++) {
- this.indexTable[i] = new Array(colsNum);
- }
- //填充索引表
- for (var rowIndex = 0, row; row = rows[rowIndex]; rowIndex++) {
- for (var cellIndex = 0, cell, cells = row.cells; cell = cells[cellIndex]; cellIndex++) {
- //修正整行被rowSpan时导致的行数计算错误
- if (cell.rowSpan > rowsNum) {
- cell.rowSpan = rowsNum;
- }
- var colIndex = cellIndex,
- rowSpan = cell.rowSpan || 1,
- colSpan = cell.colSpan || 1;
- //当已经被上一行rowSpan或者被前一列colSpan了,则跳到下一个单元格进行
- while (this.indexTable[rowIndex][colIndex]) colIndex++;
- for (var j = 0; j < rowSpan; j++) {
- for (var k = 0; k < colSpan; k++) {
- this.indexTable[rowIndex + j][colIndex + k] = {
- rowIndex:rowIndex,
- cellIndex:cellIndex,
- colIndex:colIndex,
- rowSpan:rowSpan,
- colSpan:colSpan
- }
- }
- }
- }
- }
- //修复残缺td
- for (j = 0; j < rowsNum; j++) {
- for (k = 0; k < colsNum; k++) {
- if (this.indexTable[j][k] === undefined) {
- row = rows[j];
- cell = row.cells[row.cells.length - 1];
- cell = cell ? cell.cloneNode(true) : this.table.ownerDocument.createElement("td");
- this.setCellContent(cell);
- if (cell.colSpan !== 1)cell.colSpan = 1;
- if (cell.rowSpan !== 1)cell.rowSpan = 1;
- row.appendChild(cell);
- this.indexTable[j][k] = {
- rowIndex:j,
- cellIndex:cell.cellIndex,
- colIndex:k,
- rowSpan:1,
- colSpan:1
- }
- }
- }
- }
- //当框选后删除行或者列后撤销,需要重建选区。
- var tds = domUtils.getElementsByTagName(this.table, "td"),
- selectTds = [];
- utils.each(tds, function (td) {
- if (domUtils.hasClass(td, "selectTdClass")) {
- selectTds.push(td);
- }
- });
- if (selectTds.length) {
- var start = selectTds[0],
- end = selectTds[selectTds.length - 1],
- startInfo = this.getCellInfo(start),
- endInfo = this.getCellInfo(end);
- this.selectedTds = selectTds;
- this.cellsRange = {
- beginRowIndex:startInfo.rowIndex,
- beginColIndex:startInfo.colIndex,
- endRowIndex:endInfo.rowIndex + endInfo.rowSpan - 1,
- endColIndex:endInfo.colIndex + endInfo.colSpan - 1
- };
- }
- },
- /**
- * 获取单元格的索引信息
- */
- getCellInfo:function (cell) {
- if (!cell) return;
- var cellIndex = cell.cellIndex,
- rowIndex = cell.parentNode.rowIndex,
- rowInfo = this.indexTable[rowIndex],
- numCols = this.colsNum;
- for (var colIndex = cellIndex; colIndex < numCols; colIndex++) {
- var cellInfo = rowInfo[colIndex];
- if (cellInfo.rowIndex === rowIndex && cellInfo.cellIndex === cellIndex) {
- return cellInfo;
- }
- }
- },
- /**
- * 根据行列号获取单元格
- */
- getCell:function (rowIndex, cellIndex) {
- return rowIndex < this.rowsNum && this.table.rows[rowIndex].cells[cellIndex] || null;
- },
- /**
- * 删除单元格
- */
- deleteCell:function (cell, rowIndex) {
- rowIndex = typeof rowIndex == 'number' ? rowIndex : cell.parentNode.rowIndex;
- var row = this.table.rows[rowIndex];
- row.deleteCell(cell.cellIndex);
- },
- /**
- * 根据始末两个单元格获取被框选的所有单元格范围
- */
- getCellsRange:function (cellA, cellB) {
- function checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex) {
- var tmpBeginRowIndex = beginRowIndex,
- tmpBeginColIndex = beginColIndex,
- tmpEndRowIndex = endRowIndex,
- tmpEndColIndex = endColIndex,
- cellInfo, colIndex, rowIndex;
- // 通过indexTable检查是否存在超出TableRange上边界的情况
- if (beginRowIndex > 0) {
- for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) {
- cellInfo = me.indexTable[beginRowIndex][colIndex];
- rowIndex = cellInfo.rowIndex;
- if (rowIndex < beginRowIndex) {
- tmpBeginRowIndex = Math.min(rowIndex, tmpBeginRowIndex);
- }
- }
- }
- // 通过indexTable检查是否存在超出TableRange右边界的情况
- if (endColIndex < me.colsNum) {
- for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) {
- cellInfo = me.indexTable[rowIndex][endColIndex];
- colIndex = cellInfo.colIndex + cellInfo.colSpan - 1;
- if (colIndex > endColIndex) {
- tmpEndColIndex = Math.max(colIndex, tmpEndColIndex);
- }
- }
- }
- // 检查是否有超出TableRange下边界的情况
- if (endRowIndex < me.rowsNum) {
- for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) {
- cellInfo = me.indexTable[endRowIndex][colIndex];
- rowIndex = cellInfo.rowIndex + cellInfo.rowSpan - 1;
- if (rowIndex > endRowIndex) {
- tmpEndRowIndex = Math.max(rowIndex, tmpEndRowIndex);
- }
- }
- }
- // 检查是否有超出TableRange左边界的情况
- if (beginColIndex > 0) {
- for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) {
- cellInfo = me.indexTable[rowIndex][beginColIndex];
- colIndex = cellInfo.colIndex;
- if (colIndex < beginColIndex) {
- tmpBeginColIndex = Math.min(cellInfo.colIndex, tmpBeginColIndex);
- }
- }
- }
- //递归调用直至所有完成所有框选单元格的扩展
- if (tmpBeginRowIndex != beginRowIndex || tmpBeginColIndex != beginColIndex || tmpEndRowIndex != endRowIndex || tmpEndColIndex != endColIndex) {
- return checkRange(tmpBeginRowIndex, tmpBeginColIndex, tmpEndRowIndex, tmpEndColIndex);
- } else {
- // 不需要扩展TableRange的情况
- return {
- beginRowIndex:beginRowIndex,
- beginColIndex:beginColIndex,
- endRowIndex:endRowIndex,
- endColIndex:endColIndex
- };
- }
- }
- try {
- var me = this,
- cellAInfo = me.getCellInfo(cellA);
- if (cellA === cellB) {
- return {
- beginRowIndex:cellAInfo.rowIndex,
- beginColIndex:cellAInfo.colIndex,
- endRowIndex:cellAInfo.rowIndex + cellAInfo.rowSpan - 1,
- endColIndex:cellAInfo.colIndex + cellAInfo.colSpan - 1
- };
- }
- var cellBInfo = me.getCellInfo(cellB);
- // 计算TableRange的四个边
- var beginRowIndex = Math.min(cellAInfo.rowIndex, cellBInfo.rowIndex),
- beginColIndex = Math.min(cellAInfo.colIndex, cellBInfo.colIndex),
- endRowIndex = Math.max(cellAInfo.rowIndex + cellAInfo.rowSpan - 1, cellBInfo.rowIndex + cellBInfo.rowSpan - 1),
- endColIndex = Math.max(cellAInfo.colIndex + cellAInfo.colSpan - 1, cellBInfo.colIndex + cellBInfo.colSpan - 1);
- return checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex);
- } catch (e) {
- if (debug) throw e;
- }
- },
- /**
- * 依据cellsRange获取对应的单元格集合
- */
- getCells:function (range) {
- //每次获取cells之前必须先清除上次的选择,否则会对后续获取操作造成影响
- this.clearSelected();
- var beginRowIndex = range.beginRowIndex,
- beginColIndex = range.beginColIndex,
- endRowIndex = range.endRowIndex,
- endColIndex = range.endColIndex,
- cellInfo, rowIndex, colIndex, tdHash = {}, returnTds = [];
- for (var i = beginRowIndex; i <= endRowIndex; i++) {
- for (var j = beginColIndex; j <= endColIndex; j++) {
- cellInfo = this.indexTable[i][j];
- rowIndex = cellInfo.rowIndex;
- colIndex = cellInfo.colIndex;
- // 如果Cells里已经包含了此Cell则跳过
- var key = rowIndex + '|' + colIndex;
- if (tdHash[key]) continue;
- tdHash[key] = 1;
- if (rowIndex < i || colIndex < j || rowIndex + cellInfo.rowSpan - 1 > endRowIndex || colIndex + cellInfo.colSpan - 1 > endColIndex) {
- return null;
- }
- returnTds.push(this.getCell(rowIndex, cellInfo.cellIndex));
- }
- }
- return returnTds;
- },
- /**
- * 清理已经选中的单元格
- */
- clearSelected:function () {
- removeSelectedClass(this.selectedTds);
- this.selectedTds = [];
- this.cellsRange = {};
- },
- /**
- * 根据range设置已经选中的单元格
- */
- setSelected:function (range) {
- var cells = this.getCells(range);
- addSelectedClass(cells);
- this.selectedTds = cells;
- this.cellsRange = range;
- },
- isFullRow:function () {
- var range = this.cellsRange;
- return (range.endColIndex - range.beginColIndex + 1) == this.colsNum;
- },
- isFullCol:function () {
- var range = this.cellsRange,
- table = this.table,
- ths = table.getElementsByTagName("th"),
- rows = range.endRowIndex - range.beginRowIndex + 1;
- return !ths.length ? rows == this.rowsNum : rows == this.rowsNum || (rows == this.rowsNum - 1);
- },
- /**
- * 获取视觉上的前置单元格,默认是左边,top传入时
- * @param cell
- * @param top
- */
- getNextCell:function (cell, bottom, ignoreRange) {
- try {
- var cellInfo = this.getCellInfo(cell),
- nextRowIndex, nextColIndex;
- var len = this.selectedTds.length && !ignoreRange,
- range = this.cellsRange;
- //末行或者末列没有后置单元格
- if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null;
- nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1)
- : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1);
- nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex;
- return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex);
- } catch (e) {
- showError(e);
- }
- },
- getPreviewCell:function (cell, top) {
- try {
- var cellInfo = this.getCellInfo(cell),
- previewRowIndex, previewColIndex;
- var len = this.selectedTds.length,
- range = this.cellsRange;
- //首行或者首列没有前置单元格
- if ((!top && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (top && (!len ? (cellInfo.rowIndex > (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null;
- previewRowIndex = !top ? ( !len ? cellInfo.rowIndex : range.beginRowIndex )
- : ( !len ? (cellInfo.rowIndex < 1 ? 0 : (cellInfo.rowIndex - 1)) : range.beginRowIndex);
- previewColIndex = !top ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1)
- : ( !len ? cellInfo.colIndex : range.endColIndex + 1);
- return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex);
- } catch (e) {
- showError(e);
- }
- },
- /**
- * 移动单元格中的内容
- */
- moveContent:function (cellTo, cellFrom) {
- if (isEmptyBlock(cellFrom)) return;
- if (isEmptyBlock(cellTo)) {
- cellTo.innerHTML = cellFrom.innerHTML;
- return;
- }
- var child = cellTo.lastChild;
- if (child.nodeType == 3 || !dtd.$block[child.tagName]) {
- cellTo.appendChild(cellTo.ownerDocument.createElement('br'))
- }
- while (child = cellFrom.firstChild) {
- cellTo.appendChild(child);
- }
- },
- /**
- * 向右合并单元格
- */
- mergeRight:function (cell) {
- var cellInfo = this.getCellInfo(cell),
- rightColIndex = cellInfo.colIndex + cellInfo.colSpan,
- rightCellInfo = this.indexTable[cellInfo.rowIndex][rightColIndex],
- rightCell = this.getCell(rightCellInfo.rowIndex, rightCellInfo.cellIndex);
- //合并
- cell.colSpan = cellInfo.colSpan + rightCellInfo.colSpan;
- //被合并的单元格不应存在宽度属性
- cell.removeAttribute("width");
- //移动内容
- this.moveContent(cell, rightCell);
- //删掉被合并的Cell
- this.deleteCell(rightCell, rightCellInfo.rowIndex);
- this.update();
- },
- /**
- * 向下合并单元格
- */
- mergeDown:function (cell) {
- var cellInfo = this.getCellInfo(cell),
- downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan,
- downCellInfo = this.indexTable[downRowIndex][cellInfo.colIndex],
- downCell = this.getCell(downCellInfo.rowIndex, downCellInfo.cellIndex);
- cell.rowSpan = cellInfo.rowSpan + downCellInfo.rowSpan;
- cell.removeAttribute("height");
- this.moveContent(cell, downCell);
- this.deleteCell(downCell, downCellInfo.rowIndex);
- this.update();
- },
- /**
- * 合并整个range中的内容
- */
- mergeRange:function () {
- //由于合并操作可以在任意时刻进行,所以无法通过鼠标位置等信息实时生成range,只能通过缓存实例中的cellsRange对象来访问
- var range = this.cellsRange,
- leftTopCell = this.getCell(range.beginRowIndex, this.indexTable[range.beginRowIndex][range.beginColIndex].cellIndex);
- if (leftTopCell.tagName == "TH" && range.endRowIndex !== range.beginRowIndex) {
- var index = this.indexTable,
- info = this.getCellInfo(leftTopCell);
- leftTopCell = this.getCell(1, index[1][info.colIndex].cellIndex);
- range = this.getCellsRange(leftTopCell, this.getCell(index[this.rowsNum - 1][info.colIndex].rowIndex, index[this.rowsNum - 1][info.colIndex].cellIndex));
- }
- // 删除剩余的Cells
- var cells = this.getCells(range),
- len = cells.length, cell;
- while (len--) {
- cell = cells[len];
- if (cell !== leftTopCell) {
- this.moveContent(leftTopCell, cell);
- this.deleteCell(cell);
- }
- }
- // 修改左上角Cell的rowSpan和colSpan,并调整宽度属性设置
- leftTopCell.rowSpan = range.endRowIndex - range.beginRowIndex + 1;
- leftTopCell.rowSpan > 1 && leftTopCell.removeAttribute("height");
- leftTopCell.colSpan = range.endColIndex - range.beginColIndex + 1;
- leftTopCell.colSpan > 1 && leftTopCell.removeAttribute("width");
- if (leftTopCell.rowSpan == this.rowsNum && leftTopCell.colSpan != 1) {
- leftTopCell.colSpan = 1;
- }
- if (leftTopCell.colSpan == this.colsNum && leftTopCell.rowSpan != 1) {
- var rowIndex = leftTopCell.parentNode.rowIndex;
- for (var i = 0; i < leftTopCell.rowSpan - 1; i++) {
- var row = this.table.rows[rowIndex + 1];
- row.parentNode.removeChild(row);
- }
- leftTopCell.rowSpan = 1;
- }
- this.update();
- },
- /**
- * 插入一行单元格
- */
- insertRow:function (rowIndex, sourceCell) {
- var numCols = this.colsNum,
- table = this.table,
- row = table.insertRow(rowIndex), cell,
- width = parseInt((table.offsetWidth - numCols * 20 - numCols - 1) / numCols, 10);
- //首行直接插入,无需考虑部分单元格被rowspan的情况
- if (rowIndex == 0 || rowIndex == this.rowsNum) {
- for (var colIndex = 0; colIndex < numCols; colIndex++) {
- cell = this.cloneCell(sourceCell, true);
- this.setCellContent(cell);
- cell.getAttribute('vAlign') && cell.setAttribute('vAlign', cell.getAttribute('vAlign'));
- row.appendChild(cell);
- }
- } else {
- var infoRow = this.indexTable[rowIndex],
- cellIndex = 0;
- for (colIndex = 0; colIndex < numCols; colIndex++) {
- var cellInfo = infoRow[colIndex];
- //如果存在某个单元格的rowspan穿过待插入行的位置,则修改该单元格的rowspan即可,无需插入单元格
- if (cellInfo.rowIndex < rowIndex) {
- cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);
- cell.rowSpan = cellInfo.rowSpan + 1;
- } else {
- cell = this.cloneCell(sourceCell, true);
- this.setCellContent(cell);
- row.appendChild(cell);
- }
- }
- }
- //框选时插入不触发contentchange,需要手动更新索引。
- this.update();
- return row;
- },
- /**
- * 删除一行单元格
- * @param rowIndex
- */
- deleteRow:function (rowIndex) {
- var row = this.table.rows[rowIndex],
- infoRow = this.indexTable[rowIndex],
- colsNum = this.colsNum,
- count = 0; //处理计数
- for (var colIndex = 0; colIndex < colsNum;) {
- var cellInfo = infoRow[colIndex],
- cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);
- if (cell.rowSpan > 1) {
- if (cellInfo.rowIndex == rowIndex) {
- var clone = cell.cloneNode(true);
- clone.rowSpan = cell.rowSpan - 1;
- clone.innerHTML = "";
- cell.rowSpan = 1;
- var nextRowIndex = rowIndex + 1,
- nextRow = this.table.rows[nextRowIndex],
- insertCellIndex,
- preMerged = this.getPreviewMergedCellsNum(nextRowIndex, colIndex) - count;
- if (preMerged < colIndex) {
- insertCellIndex = colIndex - preMerged - 1;
- //nextRow.insertCell(insertCellIndex);
- domUtils.insertAfter(nextRow.cells[insertCellIndex], clone);
- } else {
- if (nextRow.cells.length) nextRow.insertBefore(clone, nextRow.cells[0])
- }
- count += 1;
- //cell.parentNode.removeChild(cell);
- }
- }
- colIndex += cell.colSpan || 1;
- }
- var deleteTds = [], cacheMap = {};
- for (colIndex = 0; colIndex < colsNum; colIndex++) {
- var tmpRowIndex = infoRow[colIndex].rowIndex,
- tmpCellIndex = infoRow[colIndex].cellIndex,
- key = tmpRowIndex + "_" + tmpCellIndex;
- if (cacheMap[key])continue;
- cacheMap[key] = 1;
- cell = this.getCell(tmpRowIndex, tmpCellIndex);
- deleteTds.push(cell);
- }
- var mergeTds = [];
- utils.each(deleteTds, function (td) {
- if (td.rowSpan == 1) {
- td.parentNode.removeChild(td);
- } else {
- mergeTds.push(td);
- }
- });
- utils.each(mergeTds, function (td) {
- td.rowSpan--;
- });
- row.parentNode.removeChild(row);
- //浏览器方法本身存在bug,采用自定义方法删除
- //this.table.deleteRow(rowIndex);
- this.update();
- },
- insertCol:function (colIndex, sourceCell, defaultValue) {
- var rowsNum = this.rowsNum,
- rowIndex = 0,
- tableRow, cell,
- backWidth = parseInt((this.table.offsetWidth - (this.colsNum + 1) * 20 - (this.colsNum + 1)) / (this.colsNum + 1), 10);
- function replaceTdToTh(rowIndex, cell, tableRow) {
- if (rowIndex == 0) {
- var th = cell.nextSibling || cell.previousSibling;
- if (th.tagName == 'TH') {
- th = cell.ownerDocument.createElement("th");
- th.appendChild(cell.firstChild);
- tableRow.insertBefore(th, cell);
- domUtils.remove(cell)
- }
- }
- }
- var preCell;
- if (colIndex == 0 || colIndex == this.colsNum) {
- for (; rowIndex < rowsNum; rowIndex++) {
- tableRow = this.table.rows[rowIndex];
- preCell = tableRow.cells[colIndex == 0 ? colIndex : tableRow.cells.length];
- cell = this.cloneCell(sourceCell, true); //tableRow.insertCell(colIndex == 0 ? colIndex : tableRow.cells.length);
- this.setCellContent(cell);
- cell.setAttribute('vAlign', cell.getAttribute('vAlign'));
- preCell && cell.setAttribute('width', preCell.getAttribute('width'));
- if (!colIndex) {
- tableRow.insertBefore(cell, tableRow.cells[0]);
- } else {
- domUtils.insertAfter(tableRow.cells[tableRow.cells.length - 1], cell);
- }
- replaceTdToTh(rowIndex, cell, tableRow)
- }
- } else {
- for (; rowIndex < rowsNum; rowIndex++) {
- var cellInfo = this.indexTable[rowIndex][colIndex];
- if (cellInfo.colIndex < colIndex) {
- cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);
- cell.colSpan = cellInfo.colSpan + 1;
- } else {
- tableRow = this.table.rows[rowIndex];
- preCell = tableRow.cells[cellInfo.cellIndex];
- cell = this.cloneCell(sourceCell, true);//tableRow.insertCell(cellInfo.cellIndex);
- this.setCellContent(cell);
- cell.setAttribute('vAlign', cell.getAttribute('vAlign'));
- preCell && cell.setAttribute('width', preCell.getAttribute('width'))
- tableRow.insertBefore(cell, preCell);
- }
- replaceTdToTh(rowIndex, cell, tableRow);
- }
- }
- //框选时插入不触发contentchange,需要手动更新索引
- this.update();
- this.updateWidth(backWidth, defaultValue || {tdPadding:10, tdBorder:1});
- },
- updateWidth:function (width, defaultValue) {
- var table = this.table,
- tmpWidth = getWidth(table) - defaultValue.tdPadding * 2 - defaultValue.tdBorder + width;
- if (tmpWidth < table.ownerDocument.body.offsetWidth) {
- table.setAttribute("width", tmpWidth);
- return;
- }
- var tds = domUtils.getElementsByTagName(this.table, "td");
- utils.each(tds, function (td) {
- td.setAttribute("width", width);
- })
- },
- deleteCol:function (colIndex) {
- var indexTable = this.indexTable,
- tableRows = this.table.rows,
- backTableWidth = this.table.getAttribute("width"),
- backTdWidth = 0,
- rowsNum = this.rowsNum,
- cacheMap = {};
- for (var rowIndex = 0; rowIndex < rowsNum;) {
- var infoRow = indexTable[rowIndex],
- cellInfo = infoRow[colIndex],
- key = cellInfo.rowIndex + '_' + cellInfo.colIndex;
- // 跳过已经处理过的Cell
- if (cacheMap[key])continue;
- cacheMap[key] = 1;
- var cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);
- if (!backTdWidth) backTdWidth = cell && parseInt(cell.offsetWidth / cell.colSpan, 10).toFixed(0);
- // 如果Cell的colSpan大于1, 就修改colSpan, 否则就删掉这个Cell
- if (cell.colSpan > 1) {
- cell.colSpan--;
- } else {
- tableRows[rowIndex].deleteCell(cellInfo.cellIndex);
- }
- rowIndex += cellInfo.rowSpan || 1;
- }
- this.table.setAttribute("width", backTableWidth - backTdWidth);
- this.update();
- },
- splitToCells:function (cell) {
- var me = this,
- cells = this.splitToRows(cell);
- utils.each(cells, function (cell) {
- me.splitToCols(cell);
- })
- },
- splitToRows:function (cell) {
- var cellInfo = this.getCellInfo(cell),
- rowIndex = cellInfo.rowIndex,
- colIndex = cellInfo.colIndex,
- results = [];
- // 修改Cell的rowSpan
- cell.rowSpan = 1;
- results.push(cell);
- // 补齐单元格
- for (var i = rowIndex, endRow = rowIndex + cellInfo.rowSpan; i < endRow; i++) {
- if (i == rowIndex)continue;
- var tableRow = this.table.rows[i],
- tmpCell = tableRow.insertCell(colIndex - this.getPreviewMergedCellsNum(i, colIndex));
- tmpCell.colSpan = cellInfo.colSpan;
- this.setCellContent(tmpCell);
- tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign'));
- tmpCell.setAttribute('align', cell.getAttribute('align'));
- if (cell.style.cssText) {
- tmpCell.style.cssText = cell.style.cssText;
- }
- results.push(tmpCell);
- }
- this.update();
- return results;
- },
- getPreviewMergedCellsNum:function (rowIndex, colIndex) {
- var indexRow = this.indexTable[rowIndex],
- num = 0;
- for (var i = 0; i < colIndex;) {
- var colSpan = indexRow[i].colSpan,
- tmpRowIndex = indexRow[i].rowIndex;
- num += (colSpan - (tmpRowIndex == rowIndex ? 1 : 0));
- i += colSpan;
- }
- return num;
- },
- splitToCols:function (cell) {
- var backWidth = (cell.offsetWidth / cell.colSpan - 22).toFixed(0),
- cellInfo = this.getCellInfo(cell),
- rowIndex = cellInfo.rowIndex,
- colIndex = cellInfo.colIndex,
- results = [];
- // 修改Cell的rowSpan
- cell.colSpan = 1;
- cell.setAttribute("width", backWidth);
- results.push(cell);
- // 补齐单元格
- for (var j = colIndex, endCol = colIndex + cellInfo.colSpan; j < endCol; j++) {
- if (j == colIndex)continue;
- var tableRow = this.table.rows[rowIndex],
- tmpCell = tableRow.insertCell(this.indexTable[rowIndex][j].cellIndex + 1);
- tmpCell.rowSpan = cellInfo.rowSpan;
- this.setCellContent(tmpCell);
- tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign'));
- tmpCell.setAttribute('align', cell.getAttribute('align'));
- tmpCell.setAttribute('width', backWidth);
- if (cell.style.cssText) {
- tmpCell.style.cssText = cell.style.cssText;
- }
- //处理th的情况
- if (cell.tagName == 'TH') {
- var th = cell.ownerDocument.createElement('th');
- th.appendChild(tmpCell.firstChild);
- th.setAttribute('vAlign', cell.getAttribute('vAlign'));
- th.rowSpan = tmpCell.rowSpan;
- tableRow.insertBefore(th, tmpCell);
- domUtils.remove(tmpCell);
- }
- results.push(tmpCell);
- }
- this.update();
- return results;
- },
- isLastCell:function (cell, rowsNum, colsNum) {
- rowsNum = rowsNum || this.rowsNum;
- colsNum = colsNum || this.colsNum;
- var cellInfo = this.getCellInfo(cell);
- return ((cellInfo.rowIndex + cellInfo.rowSpan) == rowsNum) &&
- ((cellInfo.colIndex + cellInfo.colSpan) == colsNum);
- },
- getLastCell:function (cells) {
- cells = cells || this.table.getElementsByTagName("td");
- var firstInfo = this.getCellInfo(cells[0]);
- var me = this, last = cells[0],
- tr = last.parentNode,
- cellsNum = 0, cols = 0, rows;
- utils.each(cells, function (cell) {
- if (cell.parentNode == tr)cols += cell.colSpan || 1;
- cellsNum += cell.rowSpan * cell.colSpan || 1;
- });
- rows = cellsNum / cols;
- utils.each(cells, function (cell) {
- if (me.isLastCell(cell, rows, cols)) {
- last = cell;
- return false;
- }
- });
- return last;
- },
- selectRow:function (rowIndex) {
- var indexRow = this.indexTable[rowIndex],
- start = this.getCell(indexRow[0].rowIndex, indexRow[0].cellIndex),
- end = this.getCell(indexRow[this.colsNum - 1].rowIndex, indexRow[this.colsNum - 1].cellIndex),
- range = this.getCellsRange(start, end);
- this.setSelected(range);
- },
- selectTable:function () {
- var tds = this.table.getElementsByTagName("td"),
- range = this.getCellsRange(tds[0], tds[tds.length - 1]);
- this.setSelected(range);
- }
- };
- function getSelectedArr(editor) {
- var ut = getTableItemsByRange(editor).cell || getUETableBySelected(editor);
- return ut ? (ut.nodeType ? [ut] : ut.selectedTds) : [];
- }
- /**
- * 根据当前选区获取相关的table信息
- * @return {Object}
- */
- function getTableItemsByRange(editor) {
- var start = editor.selection.getStart(),
- //在table或者td边缘有可能存在选中tr的情况
- cell = start && domUtils.findParentByTagName(start, ["td", "th"], true),
- tr = cell && cell.parentNode,
- caption = start && domUtils.findParentByTagName(start, 'caption', true),
- table = caption ? caption.parentNode : tr && tr.parentNode.parentNode;
- return {
- cell:cell,
- tr:tr,
- table:table,
- caption:caption
- }
- }
- /**
- * 获取需要触发对应点击或者move事件的td对象
- * @param evt
- */
- function getTargetTd(editor, evt) {
- var target = domUtils.findParentByTagName(evt.target || evt.srcElement, ["td", "th"], true);
- //排除了非td内部以及用于代码高亮部分的td
- return target && !(editor.fireEvent("excludetable", target) === true) ? target : null;
- }
- function cloneCell(cell, ingoreMerge) {
- if (!cell || utils.isString(cell)) {
- return this.table.ownerDocument.createElement(cell || 'td');
- }
- var flag = domUtils.hasClass(cell, "selectTdClass");
- flag && domUtils.removeClasses(cell, "selectTdClass");
- var tmpCell = cell.cloneNode(true);
- if (ingoreMerge) {
- tmpCell.rowSpan = tmpCell.colSpan = 1;
- }
- tmpCell.style.borderLeftStyle = "";
- tmpCell.style.borderTopStyle = "";
- tmpCell.style.borderLeftColor = cell.style.borderRightColor;
- tmpCell.style.borderLeftWidth = cell.style.borderRightWidth;
- tmpCell.style.borderTopColor = cell.style.borderBottomColor;
- tmpCell.style.borderTopWidth = cell.style.borderBottomWidth;
- flag && domUtils.addClass(cell, "selectTdClass");
- return tmpCell;
- }
- };
- ///import core
- ///commands 右键菜单
- ///commandsName ContextMenu
- ///commandsTitle 右键菜单
- /**
- * 右键菜单
- * @function
- * @name baidu.editor.plugins.contextmenu
- * @author zhanyi
- */
- UE.plugins['contextmenu'] = function () {
- var me = this,
- lang = me.getLang( "contextMenu" ),
- menu,
- items = me.options.contextMenu || [
- {label:lang['selectall'], cmdName:'selectall'},
- {
- label:lang.deletecode,
- cmdName:'highlightcode',
- icon:'deletehighlightcode'
- },
- {
- label:lang.cleardoc,
- cmdName:'cleardoc',
- exec:function () {
- if ( confirm( lang.confirmclear ) ) {
- this.execCommand( 'cleardoc' );
- }
- }
- },
- '-',
- {
- label:lang.unlink,
- cmdName:'unlink'
- },
- '-',
- {
- group:lang.paragraph,
- icon:'justifyjustify',
- subMenu:[
- {
- label:lang.justifyleft,
- cmdName:'justify',
- value:'left'
- },
- {
- label:lang.justifyright,
- cmdName:'justify',
- value:'right'
- },
- {
- label:lang.justifycenter,
- cmdName:'justify',
- value:'center'
- },
- {
- label:lang.justifyjustify,
- cmdName:'justify',
- value:'justify'
- }
- ]
- },
- '-',
- {
- group:lang.table,
- icon:'table',
- subMenu:[
- {
- label:lang.inserttable,
- cmdName:'inserttable'
- },
- {
- label:lang.deletetable,
- cmdName:'deletetable'
- },
- {
- label:lang.signset,
- cmdName:'signset'
- },
- '-',
- {
- label:lang.deleterow,
- cmdName:'deleterow'
- },
- {
- label:lang.deletecol,
- cmdName:'deletecol'
- },
- {
- label:lang.insertcol,
- cmdName:'insertcol'
- },
- {
- label:lang.insertcolnext,
- cmdName:'insertcolnext'
- },
- {
- label:lang.insertrow,
- cmdName:'insertrow'
- },
- {
- label:lang.insertrownext,
- cmdName:'insertrownext'
- },
- '-',
- {
- label:lang.insertcaption,
- cmdName:'insertcaption'
- },
- {
- label:lang.deletecaption,
- cmdName:'deletecaption'
- },
- {
- label:lang.inserttitle,
- cmdName:'inserttitle'
- },
- {
- label:lang.deletetitle,
- cmdName:'deletetitle'
- },
- '-',
- {
- label:lang.mergecells,
- cmdName:'mergecells'
- },
- {
- label:lang.mergeright,
- cmdName:'mergeright'
- },
- {
- label:lang.mergedown,
- cmdName:'mergedown'
- },
- '-',
- {
- label:lang.splittorows,
- cmdName:'splittorows'
- },
- {
- label:lang.splittocols,
- cmdName:'splittocols'
- },
- {
- label:lang.splittocells,
- cmdName:'splittocells'
- },
- '-',
- {
- label:lang.averageDiseRow,
- cmdName:'averagedistributerow'
- },
- {
- label:lang.averageDisCol,
- cmdName:'averagedistributecol'
- },
- '-',
- {
- label:lang.edittd,
- cmdName:'edittd',
- exec:function () {
- if ( UE.ui['edittd'] ) {
- new UE.ui['edittd']( this );
- }
- this.getDialog('edittd').open();
- }
- },
- {
- label:lang.edittable,
- cmdName:'edittable',
- exec:function () {
- if ( UE.ui['edittable'] ) {
- new UE.ui['edittable']( this );
- }
- this.getDialog('edittable').open();
- }
- }
- ]
- },
- {
- group:lang.aligntd,
- icon:'aligntd',
- subMenu:[
- {
- cmdName:'cellalignment',
- value:{align:'left',vAlign:'top'}
- },
- {
- cmdName:'cellalignment',
- value:{align:'center',vAlign:'top'}
- },
- {
- cmdName:'cellalignment',
- value:{align:'right',vAlign:'top'}
- },
- {
- cmdName:'cellalignment',
- value:{align:'left',vAlign:'middle'}
- },
- {
- cmdName:'cellalignment',
- value:{align:'center',vAlign:'middle'}
- },
- {
- cmdName:'cellalignment',
- value:{align:'right',vAlign:'middle'}
- },
- {
- cmdName:'cellalignment',
- value:{align:'left',vAlign:'bottom'}
- },
- {
- cmdName:'cellalignment',
- value:{align:'center',vAlign:'bottom'}
- },
- {
- cmdName:'cellalignment',
- value:{align:'right',vAlign:'bottom'}
- }
- ]
- },
- {
- group:lang.aligntable,
- icon:'aligntable',
- subMenu:[
- {
- cmdName:'tablealignment',
- label:lang.tableleft,
- value:['float','left']
- },
- {
- cmdName:'tablealignment',
- label:lang.tablecenter,
- value:['margin','0 auto']
- },
- {
- cmdName:'tablealignment',
- label:lang.tableright,
- value:['float','right']
- }
- ]
- },
- '-',
- {
- label:lang.insertparagraphbefore,
- cmdName:'insertparagraph',
- value:true
- },
- {
- label:lang.insertparagraphafter,
- cmdName:'insertparagraph'
- },
- {
- label:lang['copy'],
- cmdName:'copy',
- exec:function () {
- alert( lang.copymsg );
- },
- query:function () {
- return 0;
- }
- },
- {
- label:lang['paste'],
- cmdName:'paste',
- exec:function () {
- alert( lang.pastemsg );
- },
- query:function () {
- return 0;
- }
- },{
- label:lang['highlightcode'],
- cmdName:'highlightcode',
- exec:function () {
- if ( UE.ui['highlightcode'] ) {
- new UE.ui['highlightcode']( this );
- }
- this.ui._dialogs['highlightcodeDialog'].open();
- }
- }
- ];
- if ( !items.length ) {
- return;
- }
- var uiUtils = UE.ui.uiUtils;
- me.addListener( 'contextmenu', function ( type, evt ) {
- var offset = uiUtils.getViewportOffsetByEvent( evt );
- me.fireEvent( 'beforeselectionchange' );
- if ( menu ) {
- menu.destroy();
- }
- for ( var i = 0, ti, contextItems = []; ti = items[i]; i++ ) {
- var last;
- (function ( item ) {
- if ( item == '-' ) {
- if ( (last = contextItems[contextItems.length - 1 ] ) && last !== '-' ) {
- contextItems.push( '-' );
- }
- } else if ( item.hasOwnProperty( "group" ) ) {
- for ( var j = 0, cj, subMenu = []; cj = item.subMenu[j]; j++ ) {
- (function ( subItem ) {
- if ( subItem == '-' ) {
- if ( (last = subMenu[subMenu.length - 1 ] ) && last !== '-' ) {
- subMenu.push( '-' );
- }else{
- subMenu.splice(subMenu.length-1);
- }
- } else {
- if ( (me.commands[subItem.cmdName] || UE.commands[subItem.cmdName] || subItem.query) &&
- (subItem.query ? subItem.query() : me.queryCommandState( subItem.cmdName )) > -1 ) {
- subMenu.push( {
- 'label':subItem.label || me.getLang( "contextMenu." + subItem.cmdName + (subItem.value || '') )||"",
- 'className':'edui-for-' +subItem.cmdName,
- onclick:subItem.exec ? function () {
- subItem.exec.call( me );
- } : function () {
- me.execCommand( subItem.cmdName, subItem.value );
- }
- } );
- }
- }
- })( cj );
- }
- if ( subMenu.length ) {
- function getLabel(){
- switch (item.icon){
- case "table":
- return me.getLang( "contextMenu.table" );
- case "justifyjustify":
- return me.getLang( "contextMenu.paragraph" );
- case "aligntd":
- return me.getLang("contextMenu.aligntd");
- case "aligntable":
- return me.getLang("contextMenu.aligntable");
- default :
- return '';
- }
- }
- contextItems.push( {
- //todo 修正成自动获取方式
- 'label':getLabel(),
- className:'edui-for-' + item.icon,
- 'subMenu':{
- items:subMenu,
- editor:me
- }
- } );
- }
- } else {
- //有可能commmand没有加载右键不能出来,或者没有command也想能展示出来添加query方法
- if ( (me.commands[item.cmdName] || UE.commands[item.cmdName] || item.query) &&
- (item.query ? item.query.call(me) : me.queryCommandState( item.cmdName )) > -1 ) {
- //highlight todo
- if ( item.cmdName == 'highlightcode' ) {
- if(me.queryCommandState( item.cmdName ) == 1 && item.icon != 'deletehighlightcode'){
- return;
- }
- if(me.queryCommandState( item.cmdName ) != 1 && item.icon == 'deletehighlightcode'){
- return;
- }
- }
- contextItems.push( {
- 'label':item.label || me.getLang( "contextMenu." + item.cmdName ),
- className:'edui-for-' + (item.icon ? item.icon : item.cmdName + (item.value || '')),
- onclick:item.exec ? function () {
- item.exec.call( me );
- } : function () {
- me.execCommand( item.cmdName, item.value );
- }
- } );
- }
- }
- })( ti );
- }
- if ( contextItems[contextItems.length - 1] == '-' ) {
- contextItems.pop();
- }
- menu = new UE.ui.Menu( {
- items:contextItems,
- editor:me
- } );
- menu.render();
- menu.showAt( offset );
- domUtils.preventDefault( evt );
- if ( browser.ie ) {
- var ieRange;
- try {
- ieRange = me.selection.getNative().createRange();
- } catch ( e ) {
- return;
- }
- if ( ieRange.item ) {
- var range = new dom.Range( me.document );
- range.selectNode( ieRange.item( 0 ) ).select( true, true );
- }
- }
- } );
- };
- ///import core
- ///commands 加粗,斜体,上标,下标
- ///commandsName Bold,Italic,Subscript,Superscript
- ///commandsTitle 加粗,加斜,下标,上标
- /**
- * b u i等基础功能实现
- * @function
- * @name baidu.editor.execCommands
- * @param {String} cmdName bold加粗。italic斜体。subscript上标。superscript下标。
- */
- UE.plugins['basestyle'] = function(){
- var basestyles = {
- 'bold':['strong','b'],
- 'italic':['em','i'],
- 'subscript':['sub'],
- 'superscript':['sup']
- },
- getObj = function(editor,tagNames){
- return domUtils.filterNodeList(editor.selection.getStartElementPath(),tagNames);
- },
- me = this;
- //添加快捷键
- me.addshortcutkey({
- "Bold" : "ctrl+66",//^B
- "Italic" : "ctrl+73", //^I
- "Underline" : "ctrl+85"//^U
- });
- for ( var style in basestyles ) {
- (function( cmd, tagNames ) {
- me.commands[cmd] = {
- execCommand : function( cmdName ) {
- var range = me.selection.getRange(),obj = getObj(this,tagNames);
- if ( range.collapsed ) {
- if ( obj ) {
- var tmpText = me.document.createTextNode('');
- range.insertNode( tmpText ).removeInlineStyle( tagNames );
- range.setStartBefore(tmpText);
- domUtils.remove(tmpText);
- } else {
- var tmpNode = range.document.createElement( tagNames[0] );
- if(cmdName == 'superscript' || cmdName == 'subscript'){
- tmpText = me.document.createTextNode('');
- range.insertNode(tmpText)
- .removeInlineStyle(['sub','sup'])
- .setStartBefore(tmpText)
- .collapse(true);
- }
- range.insertNode( tmpNode ).setStart( tmpNode, 0 );
- }
- range.collapse( true );
- } else {
- if(cmdName == 'superscript' || cmdName == 'subscript'){
- if(!obj || obj.tagName.toLowerCase() != cmdName){
- range.removeInlineStyle(['sub','sup']);
- }
- }
- obj ? range.removeInlineStyle( tagNames ) : range.applyInlineStyle( tagNames[0] );
- }
- range.select();
- },
- queryCommandState : function() {
- return getObj(this,tagNames) ? 1 : 0;
- }
- };
- })( style, basestyles[style] );
- }
- };
- ///import core
- ///commands 选区路径
- ///commandsName ElementPath,elementPathEnabled
- ///commandsTitle 选区路径
- /**
- * 选区路径
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName elementpath选区路径
- */
- UE.plugins['elementpath'] = function(){
- var currentLevel,
- tagNames,
- me = this;
- me.setOpt('elementPathEnabled',true);
- if(!me.options.elementPathEnabled){
- return;
- }
- me.commands['elementpath'] = {
- execCommand : function( cmdName, level ) {
- var start = tagNames[level],
- range = me.selection.getRange();
- currentLevel = level*1;
- range.selectNode(start).select();
- },
- queryCommandValue : function() {
- //产生一个副本,不能修改原来的startElementPath;
- var parents = [].concat(this.selection.getStartElementPath()).reverse(),
- names = [];
- tagNames = parents;
- for(var i=0,ci;ci=parents[i];i++){
- if(ci.nodeType == 3) {
- continue;
- }
- var name = ci.tagName.toLowerCase();
- if(name == 'img' && ci.getAttribute('anchorname')){
- name = 'anchor';
- }
- names[i] = name;
- if(currentLevel == i){
- currentLevel = -1;
- break;
- }
- }
- return names;
- }
- };
- };
- ///import core
- ///import plugins\removeformat.js
- ///commands 格式刷
- ///commandsName FormatMatch
- ///commandsTitle 格式刷
- /**
- * 格式刷,只格式inline的
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName formatmatch执行格式刷
- */
- UE.plugins['formatmatch'] = function(){
- var me = this,
- list = [],img,
- flag = 0;
- me.addListener('reset',function(){
- list = [];
- flag = 0;
- });
- function addList(type,evt){
-
- if(browser.webkit){
- var target = evt.target.tagName == 'IMG' ? evt.target : null;
- }
- function addFormat(range){
- if(text){
- range.selectNode(text);
- }
- return range.applyInlineStyle(list[list.length-1].tagName,null,list);
- }
- me.undoManger && me.undoManger.save();
- var range = me.selection.getRange(),
- imgT = target || range.getClosedNode();
- if(img && imgT && imgT.tagName == 'IMG'){
- //trace:964
- imgT.style.cssText += ';float:' + (img.style.cssFloat || img.style.styleFloat ||'none') + ';display:' + (img.style.display||'inline');
- img = null;
- }else{
- if(!img){
- var collapsed = range.collapsed;
- if(collapsed){
- var text = me.document.createTextNode('match');
- range.insertNode(text).select();
- }
- me.__hasEnterExecCommand = true;
- //不能把block上的属性干掉
- //trace:1553
- var removeFormatAttributes = me.options.removeFormatAttributes;
- me.options.removeFormatAttributes = '';
- me.execCommand('removeformat');
- me.options.removeFormatAttributes = removeFormatAttributes;
- me.__hasEnterExecCommand = false;
- //trace:969
- range = me.selection.getRange();
- if(list.length){
- addFormat(range);
- }
- if(text){
- range.setStartBefore(text).collapse(true);
- }
- range.select();
- text && domUtils.remove(text);
- }
- }
- me.undoManger && me.undoManger.save();
- me.removeListener('mouseup',addList);
- flag = 0;
- }
- me.commands['formatmatch'] = {
- execCommand : function( cmdName ) {
-
- if(flag){
- flag = 0;
- list = [];
- me.removeListener('mouseup',addList);
- return;
- }
-
- var range = me.selection.getRange();
- img = range.getClosedNode();
- if(!img || img.tagName != 'IMG'){
- range.collapse(true).shrinkBoundary();
- var start = range.startContainer;
- list = domUtils.findParents(start,true,function(node){
- return !domUtils.isBlockElm(node) && node.nodeType == 1;
- });
- //a不能加入格式刷, 并且克隆节点
- for(var i=0,ci;ci=list[i];i++){
- if(ci.tagName == 'A'){
- list.splice(i,1);
- break;
- }
- }
- }
- me.addListener('mouseup',addList);
- flag = 1;
- },
- queryCommandState : function() {
- return flag;
- },
- notNeedUndo : 1
- };
- };
- ///import core
- ///commands 查找替换
- ///commandsName SearchReplace
- ///commandsTitle 查询替换
- ///commandsDialog dialogs\searchreplace
- /**
- * @description 查找替换
- * @author zhanyi
- */
- UE.plugins['searchreplace'] = function(){
- var currentRange,
- first,
- me = this;
- me.addListener('reset',function(){
- currentRange = null;
- first = null;
- });
- me.commands['searchreplace'] = {
- execCommand : function(cmdName,opt){
- var me = this,
- sel = me.selection,
- range,
- nativeRange,
- num = 0,
- opt = utils.extend(opt,{
- all : false,
- casesensitive : false,
- dir : 1
- },true);
- if(browser.ie){
- while(1){
- var tmpRange;
- nativeRange = me.document.selection.createRange();
- tmpRange = nativeRange.duplicate();
- tmpRange.moveToElementText(me.document.body);
- if(opt.all){
- first = 0;
- opt.dir = 1;
- if(currentRange){
- tmpRange.setEndPoint(opt.dir == -1 ? 'EndToStart' : 'StartToEnd',currentRange);
- }
- tmpRange.moveToElementText(me.document.body);
- }else{
- tmpRange.setEndPoint(opt.dir == -1 ? 'EndToStart' : 'StartToEnd',nativeRange);
- if(opt.hasOwnProperty("replaceStr")){
- tmpRange.setEndPoint(opt.dir == -1 ? 'StartToEnd' : 'EndToStart',nativeRange);
- }
- }
- nativeRange = tmpRange.duplicate();
- if(!tmpRange.findText(opt.searchStr,opt.dir,opt.casesensitive ? 4 : 0)){
- currentRange = null;
- tmpRange = me.document.selection.createRange();
- tmpRange.scrollIntoView();
- return num;
- }
- tmpRange.select();
- //替换
- if(opt.hasOwnProperty("replaceStr")){
- range = sel.getRange();
- range.deleteContents().insertNode(range.document.createTextNode(opt.replaceStr)).select();
- currentRange = sel.getNative().createRange();
- }
- num++;
- if(!opt.all){
- break;
- }
- }
- }else{
- var w = me.window,nativeSel = sel.getNative(),tmpRange;
- while(1){
- if(opt.all){
- if(currentRange){
- currentRange.collapse(false);
- nativeRange = currentRange;
- }else{
- nativeRange = me.document.createRange();
- }
- nativeRange.setStart(me.document.body,0);
- nativeRange.collapse(true);
- nativeSel.removeAllRanges();
- nativeSel.addRange( nativeRange );
- first = 0;
- opt.dir = 1;
- }else{
- //safari弹出层,原生已经找不到range了,所以需要先选回来,再取原生
- if(browser.safari){
- me.selection.getRange().select();
- }
- nativeRange = w.getSelection().getRangeAt(0);
- if(opt.hasOwnProperty("replaceStr")){
- nativeRange.collapse(opt.dir == 1 ? true : false);
- }
- }
- //如果是第一次并且海选中了内容那就要清除,为find做准备
- if(!first){
- nativeRange.collapse( opt.dir <0 ? true : false);
- nativeSel.removeAllRanges();
- nativeSel.addRange( nativeRange );
- }else{
- nativeSel.removeAllRanges();
- }
- if(!w.find(opt.searchStr,opt.casesensitive,opt.dir < 0 ? true : false) ) {
- currentRange = null;
- nativeSel.removeAllRanges();
- return num;
- }
- first = 0;
- range = w.getSelection().getRangeAt(0);
- if(!range.collapsed){
- if(opt.hasOwnProperty("replaceStr")){
- range.deleteContents();
- var text = w.document.createTextNode(opt.replaceStr);
- range.insertNode(text);
- range.selectNode(text);
- nativeSel.addRange(range);
- currentRange = range.cloneRange();
- }
- }
- num++;
- if(!opt.all){
- break;
- }
- }
- }
- return true;
- }
- };
- };
- ///import core
- ///commands 自定义样式
- ///commandsName CustomStyle
- ///commandsTitle 自定义样式
- UE.plugins['customstyle'] = function() {
- var me = this;
- me.setOpt({ 'customstyle':[
- {tag:'h1',name:'tc', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;'},
- {tag:'h1',name:'tl', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;'},
- {tag:'span',name:'im', style:'font-size:16px;font-style:italic;font-weight:bold;line-height:18px;'},
- {tag:'span',name:'hi', style:'font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;'}
- ]});
- me.commands['customstyle'] = {
- execCommand : function(cmdName, obj) {
- var me = this,
- tagName = obj.tag,
- node = domUtils.findParent(me.selection.getStart(), function(node) {
- return node.getAttribute('label');
- }, true),
- range,bk,tmpObj = {};
- for (var p in obj) {
- if(obj[p]!==undefined)
- tmpObj[p] = obj[p];
- }
- delete tmpObj.tag;
- if (node && node.getAttribute('label') == obj.label) {
- range = this.selection.getRange();
- bk = range.createBookmark();
- if (range.collapsed) {
- //trace:1732 删掉自定义标签,要有p来回填站位
- if(dtd.$block[node.tagName]){
- var fillNode = me.document.createElement('p');
- domUtils.moveChild(node, fillNode);
- node.parentNode.insertBefore(fillNode, node);
- domUtils.remove(node);
- }else{
- domUtils.remove(node,true);
- }
- } else {
- var common = domUtils.getCommonAncestor(bk.start, bk.end),
- nodes = domUtils.getElementsByTagName(common, tagName);
- if(new RegExp(tagName,'i').test(common.tagName)){
- nodes.push(common);
- }
- for (var i = 0,ni; ni = nodes[i++];) {
- if (ni.getAttribute('label') == obj.label) {
- var ps = domUtils.getPosition(ni, bk.start),pe = domUtils.getPosition(ni, bk.end);
- if ((ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)
- &&
- (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)
- )
- if (dtd.$block[tagName]) {
- var fillNode = me.document.createElement('p');
- domUtils.moveChild(ni, fillNode);
- ni.parentNode.insertBefore(fillNode, ni);
- }
- domUtils.remove(ni, true);
- }
- }
- node = domUtils.findParent(common, function(node) {
- return node.getAttribute('label') == obj.label;
- }, true);
- if (node) {
- domUtils.remove(node, true);
- }
- }
- range.moveToBookmark(bk).select();
- } else {
- if (dtd.$block[tagName]) {
- this.execCommand('paragraph', tagName, tmpObj,'customstyle');
- range = me.selection.getRange();
- if (!range.collapsed) {
- range.collapse();
- node = domUtils.findParent(me.selection.getStart(), function(node) {
- return node.getAttribute('label') == obj.label;
- }, true);
- var pNode = me.document.createElement('p');
- domUtils.insertAfter(node, pNode);
- domUtils.fillNode(me.document, pNode);
- range.setStart(pNode, 0).setCursor();
- }
- } else {
- range = me.selection.getRange();
- if (range.collapsed) {
- node = me.document.createElement(tagName);
- domUtils.setAttributes(node, tmpObj);
- range.insertNode(node).setStart(node, 0).setCursor();
- return;
- }
- bk = range.createBookmark();
- range.applyInlineStyle(tagName, tmpObj).moveToBookmark(bk).select();
- }
- }
- },
- queryCommandValue : function() {
- var parent = domUtils.filterNodeList(
- this.selection.getStartElementPath(),
- function(node){return node.getAttribute('label')}
- );
- return parent ? parent.getAttribute('label') : '';
- }
- };
- //当去掉customstyle是,如果是块元素,用p代替
- me.addListener('keyup', function(type, evt) {
- var keyCode = evt.keyCode || evt.which;
- if (keyCode == 32 || keyCode == 13) {
- var range = me.selection.getRange();
- if (range.collapsed) {
- var node = domUtils.findParent(me.selection.getStart(), function(node) {
- return node.getAttribute('label');
- }, true);
- if (node && dtd.$block[node.tagName] && domUtils.isEmptyNode(node)) {
- var p = me.document.createElement('p');
- domUtils.insertAfter(node, p);
- domUtils.fillNode(me.document, p);
- domUtils.remove(node);
- range.setStart(p, 0).setCursor();
- }
- }
- }
- });
- };
- ///import core
- ///commands 远程图片抓取
- ///commandsName catchRemoteImage,catchremoteimageenable
- ///commandsTitle 远程图片抓取
- /**
- * 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片
- *
- */
- UE.plugins['catchremoteimage'] = function () {
- if (this.options.catchRemoteImageEnable===false){
- return;
- }
- var me = this;
- this.setOpt({
- localDomain:["127.0.0.1","localhost","img.baidu.com"],
- separater:'ue_separate_ue',
- catchFieldName:"upfile",
- catchRemoteImageEnable:true
- });
- var ajax = UE.ajax,
- localDomain = me.options.localDomain ,
- catcherUrl = me.options.catcherUrl,
- separater = me.options.separater;
- function catchremoteimage(imgs, callbacks) {
- var submitStr = imgs.join(separater);
- var tmpOption = {
- timeout:60000, //单位:毫秒,回调请求超时设置。目标用户如果网速不是很快的话此处建议设置一个较大的数值
- onsuccess:callbacks["success"],
- onerror:callbacks["error"]
- };
- tmpOption[me.options.catchFieldName] = submitStr;
- ajax.request(catcherUrl, tmpOption);
- }
- me.addListener("afterpaste", function () {
- me.fireEvent("catchRemoteImage");
- });
- me.addListener("catchRemoteImage", function () {
- var remoteImages = [];
- var imgs = domUtils.getElementsByTagName(me.document, "img");
- var test = function (src,urls) {
- for (var j = 0, url; url = urls[j++];) {
- if (src.indexOf(url) !== -1) {
- return true;
- }
- }
- return false;
- };
- for (var i = 0, ci; ci = imgs[i++];) {
- if (ci.getAttribute("word_img")){
- continue;
- }
- var src = ci.getAttribute("data_ue_src") || ci.src || "";
- if (/^(https?|ftp):/i.test(src) && !test(src,localDomain)) {
- remoteImages.push(src);
- }
- }
- if (remoteImages.length) {
- catchremoteimage(remoteImages, {
- //成功抓取
- success:function (xhr) {
- try {
- var info = eval("(" + xhr.responseText + ")");
- } catch (e) {
- return;
- }
- var srcUrls = info.srcUrl.split(separater),
- urls = info.url.split(separater);
- for (var i = 0, ci; ci = imgs[i++];) {
- var src = ci.getAttribute("data_ue_src") || ci.src || "";
- for (var j = 0, cj; cj = srcUrls[j++];) {
- var url = urls[j - 1];
- if (src == cj && url != "error") { //抓取失败时不做替换处理
- //地址修正
- var newSrc = me.options.catcherPath + url;
- domUtils.setAttributes(ci, {
- "src":newSrc,
- "data_ue_src":newSrc
- });
- break;
- }
- }
- }
- me.fireEvent('catchremotesuccess')
- },
- //回调失败,本次请求超时
- error:function () {
- me.fireEvent("catchremoteerror");
- }
- });
- }
- });
- };
- ///import core
- ///import plugins\inserthtml.js
- ///import plugins\image.js
- ///commandsName snapscreen
- ///commandsTitle 截屏
- /**
- * 截屏插件
- */
- UE.plugins['snapscreen'] = function(){
- var me = this,
- doc,
- snapplugin;
- me.addListener("ready",function(){
- var container = me.container;
- doc = container.ownerDocument || container.document;
- snapplugin = doc.createElement("object");
- snapplugin.type = "application/x-pluginbaidusnap";
- snapplugin.style.cssText = "position:absolute;left:-9999px;";
- snapplugin.setAttribute("width","0");
- snapplugin.setAttribute("height","0");
- container.appendChild(snapplugin);
- });
- me.commands['snapscreen'] = {
- execCommand: function(){
- var me = this,lang = me.getLang("snapScreen_plugin");
- me.setOpt({
- snapscreenServerPort: 80 //屏幕截图的server端端口
- ,snapscreenImgAlign: '' //截图的图片默认的排版方式
- });
- var editorOptions = me.options;
- var onSuccess = function(rs){
- try{
- rs = eval("("+ rs +")");
- }catch(e){
- alert(lang.callBackErrorMsg);
- return;
- }
- if(rs.state != 'SUCCESS'){
- alert(rs.state);
- return;
- }
- me.execCommand('insertimage', {
- src: editorOptions.snapscreenPath + rs.url,
- floatStyle: editorOptions.snapscreenImgAlign,
- data_ue_src:editorOptions.snapscreenPath + rs.url
- });
- };
- var onStartUpload = function(){
- //开始截图上传
- };
- var onError = function(){
- alert(lang.uploadErrorMsg);
- };
- try{
- var ret =snapplugin.saveSnapshot(editorOptions.snapscreenHost, editorOptions.snapscreenServerUrl, editorOptions.snapscreenServerPort.toString());
- onSuccess(ret);
- }catch(e){
- me.ui._dialogs['snapscreenDialog'].open();
- }
- },
- queryCommandState: function(){
- return this.highlight ? -1 :0;
- }
- };
- }
- ///import core
- ///commands 插入空行
- ///commandsName insertparagraph
- ///commandsTitle 插入空行
- /**
- * 插入空行
- * @function
- * @name baidu.editor.execCommand
- * @param {String} cmdName insertparagraph
- */
- UE.commands['insertparagraph'] = {
- execCommand : function( cmdName,front) {
- var me = this,
- range = me.selection.getRange(),
- start = range.startContainer,tmpNode;
- while(start ){
- if(domUtils.isBody(start)){
- break;
- }
- tmpNode = start;
- start = start.parentNode;
- }
- if(tmpNode){
- var p = me.document.createElement('p');
- if(front){
- tmpNode.parentNode.insertBefore(p,tmpNode)
- }else{
- tmpNode.parentNode.insertBefore(p,tmpNode.nextSibling)
- }
- domUtils.fillNode(me.document,p);
- range.setStart(p,0).setCursor(false,true);
- }
- }
- };
- ///import core
- ///import plugins/inserthtml.js
- ///commands 百度应用
- ///commandsName webapp
- ///commandsTitle 百度应用
- ///commandsDialog dialogs\webapp
- UE.plugins['webapp'] = function () {
- var me = this;
- function createInsertStr( obj, toIframe, addParagraph ) {
- return !toIframe ?
- (addParagraph ? '<p>' : '') + '<img title="'+obj.title+'" width="' + obj.width + '" height="' + obj.height + '"' +
- ' src="' + me.options.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif" style="background:url(' + obj.logo+') no-repeat center center; border:1px solid gray;" class="edui-faked-webapp" _url="' + obj.url + '" />' +
- (addParagraph ? '</p>' : '')
- :
- '<iframe class="edui-faked-webapp" title="'+obj.title+'" width="' + obj.width + '" height="' + obj.height + '" scrolling="no" frameborder="0" src="' + obj.url + '" logo_url = '+obj.logo+'></iframe>';
- }
- function switchImgAndIframe( img2frame ) {
- var tmpdiv,
- nodes = domUtils.getElementsByTagName( me.document, !img2frame ? "iframe" : "img" );
- for ( var i = 0, node; node = nodes[i++]; ) {
- if ( node.className != "edui-faked-webapp" ){
- continue;
- }
- tmpdiv = me.document.createElement( "div" );
- tmpdiv.innerHTML = createInsertStr( img2frame ? {url:node.getAttribute( "_url" ), width:node.width, height:node.height,title:node.title,logo:node.style.backgroundImage.replace("url(","").replace(")","")} : {url:node.getAttribute( "src", 2 ),title:node.title, width:node.width, height:node.height,logo:node.getAttribute("logo_url")}, img2frame ? true : false,false );
- node.parentNode.replaceChild( tmpdiv.firstChild, node );
- }
- }
- me.addListener( "beforegetcontent", function () {
- switchImgAndIframe( true );
- } );
- me.addListener( 'aftersetcontent', function () {
- switchImgAndIframe( false );
- } );
- me.addListener( 'aftergetcontent', function ( cmdName ) {
- if ( cmdName == 'aftergetcontent' && me.queryCommandState( 'source' ) ){
- return;
- }
- switchImgAndIframe( false );
- } );
- me.commands['webapp'] = {
- execCommand:function ( cmd, obj ) {
- me.execCommand( "inserthtml", createInsertStr( obj, false,true ) );
- }
- };
- };
- ///import core
- ///import plugins\inserthtml.js
- ///import plugins\cleardoc.js
- ///commands 模板
- ///commandsName template
- ///commandsTitle 模板
- ///commandsDialog dialogs\template
- UE.plugins['template'] = function () {
- UE.commands['template'] = {
- execCommand:function (cmd, obj) {
- obj.html && this.execCommand("inserthtml", obj.html);
- }
- };
- this.addListener("click", function (type, evt) {
- var el = evt.target || evt.srcElement,
- range = this.selection.getRange();
- var tnode = domUtils.findParent(el, function (node) {
- if (node.className && domUtils.hasClass(node, "ue_t")) {
- return node;
- }
- }, true);
- tnode && range.selectNode(tnode).shrinkBoundary().select();
- });
- this.addListener("keydown", function (type, evt) {
- var range = this.selection.getRange();
- if (!range.collapsed) {
- if (!evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) {
- var tnode = domUtils.findParent(range.startContainer, function (node) {
- if (node.className && domUtils.hasClass(node, "ue_t")) {
- return node;
- }
- }, true);
- if (tnode) {
- domUtils.removeClasses(tnode, ["ue_t"]);
- }
- }
- }
- });
- };
- ///import core
- ///import plugins/inserthtml.js
- ///commands 音乐
- ///commandsName Music
- ///commandsTitle 插入音乐
- ///commandsDialog dialogs\music
- UE.plugins['music'] = function () {
- var me = this,
- div;
- /**
- * 创建插入音乐字符窜
- * @param url 音乐地址
- * @param width 音乐宽度
- * @param height 音乐高度
- * @param align 阴雨对齐
- * @param toEmbed 是否以flash代替显示
- * @param addParagraph 是否需要添加P标签
- */
- function creatInsertStr(url,width,height,align,toEmbed,addParagraph){
- return !toEmbed ?
- (addParagraph? ('<p '+ (align !="none" ? ( align == "center"? ' style="text-align:center;" ':' style="float:"'+ align ) : '') + '>'): '') +
- '<img align="'+align+'" width="'+ width +'" height="' + height + '" _url="'+url+'" class="edui-faked-music"' +
- ' src="'+me.options.langPath+me.options.lang+'/images/music.png" />' +
- (addParagraph?'</p>':'')
- :
- '<embed type="application/x-shockwave-flash" class="edui-faked-music" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
- ' src="' + url + '" width="' + width + '" height="' + height + '" align="' + align + '"' +
- ( align !="none" ? ' style= "'+ ( align == "center"? "display:block;":" float: "+ align ) + '"' :'' ) +
- ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >';
- }
- function switchImgAndEmbed(img2embed) {
- var tmpdiv,
- nodes = domUtils.getElementsByTagName(me.document, !img2embed ? "embed" : "img");
- for (var i = 0, node; node = nodes[i++];) {
- if (node.className != "edui-faked-music") {
- continue;
- }
- tmpdiv = me.document.createElement("div");
- //先看float在看align,浮动有的是时候是在float上定义的
- var align = domUtils.getComputedStyle(node,'float');
- align = align == 'none' ? (node.getAttribute('align') || '') : align;
- tmpdiv.innerHTML = creatInsertStr(img2embed ? node.getAttribute("_url") : node.getAttribute("src"), node.width, node.height, align, img2embed);
- node.parentNode.replaceChild(tmpdiv.firstChild, node);
- }
- }
- me.addListener("beforegetcontent", function () {
- switchImgAndEmbed(true);
- });
- me.addListener('aftersetcontent', function () {
- switchImgAndEmbed(false);
- });
- me.addListener('aftergetcontent', function (cmdName) {
- if (cmdName == 'aftergetcontent' && me.queryCommandState('source')) {
- return;
- }
- switchImgAndEmbed(false);
- });
- me.commands["music"] = {
- execCommand:function (cmd, musicObj) {
- var me = this,
- str = creatInsertStr(musicObj.url, musicObj.width || 400, musicObj.height || 95, "none", false, true);
- me.execCommand("inserthtml",str);
- },
- queryCommandState:function () {
- var me = this,
- img = me.selection.getRange().getClosedNode(),
- flag = img && (img.className == "edui-faked-music");
- return flag ? 1 : 0;
- }
- };
- };
- var baidu = baidu || {};
- baidu.editor = baidu.editor || {};
- baidu.editor.ui = {};
- (function (){
- var browser = baidu.editor.browser,
- domUtils = baidu.editor.dom.domUtils;
- var magic = '$EDITORUI';
- var root = window[magic] = {};
- var uidMagic = 'ID' + magic;
- var uidCount = 0;
- var uiUtils = baidu.editor.ui.uiUtils = {
- uid: function (obj){
- return (obj ? obj[uidMagic] || (obj[uidMagic] = ++ uidCount) : ++ uidCount);
- },
- hook: function ( fn, callback ) {
- var dg;
- if (fn && fn._callbacks) {
- dg = fn;
- } else {
- dg = function (){
- var q;
- if (fn) {
- q = fn.apply(this, arguments);
- }
- var callbacks = dg._callbacks;
- var k = callbacks.length;
- while (k --) {
- var r = callbacks[k].apply(this, arguments);
- if (q === undefined) {
- q = r;
- }
- }
- return q;
- };
- dg._callbacks = [];
- }
- dg._callbacks.push(callback);
- return dg;
- },
- createElementByHtml: function (html){
- var el = document.createElement('div');
- el.innerHTML = html;
- el = el.firstChild;
- el.parentNode.removeChild(el);
- return el;
- },
- getViewportElement: function (){
- return (browser.ie && browser.quirks) ?
- document.body : document.documentElement;
- },
- getClientRect: function (element){
- var bcr;
- //trace IE6下在控制编辑器显隐时可能会报错,catch一下
- try{
- bcr = element.getBoundingClientRect();
- }catch(e){
- bcr={left:0,top:0,height:0,width:0}
- }
- var rect = {
- left: Math.round(bcr.left),
- top: Math.round(bcr.top),
- height: Math.round(bcr.bottom - bcr.top),
- width: Math.round(bcr.right - bcr.left)
- };
- var doc;
- while ((doc = element.ownerDocument) !== document &&
- (element = domUtils.getWindow(doc).frameElement)) {
- bcr = element.getBoundingClientRect();
- rect.left += bcr.left;
- rect.top += bcr.top;
- }
- rect.bottom = rect.top + rect.height;
- rect.right = rect.left + rect.width;
- return rect;
- },
- getViewportRect: function (){
- var viewportEl = uiUtils.getViewportElement();
- var width = (window.innerWidth || viewportEl.clientWidth) | 0;
- var height = (window.innerHeight ||viewportEl.clientHeight) | 0;
- return {
- left: 0,
- top: 0,
- height: height,
- width: width,
- bottom: height,
- right: width
- };
- },
- setViewportOffset: function (element, offset){
- var rect;
- var fixedLayer = uiUtils.getFixedLayer();
- if (element.parentNode === fixedLayer) {
- element.style.left = offset.left + 'px';
- element.style.top = offset.top + 'px';
- } else {
- domUtils.setViewportOffset(element, offset);
- }
- },
- getEventOffset: function (evt){
- var el = evt.target || evt.srcElement;
- var rect = uiUtils.getClientRect(el);
- var offset = uiUtils.getViewportOffsetByEvent(evt);
- return {
- left: offset.left - rect.left,
- top: offset.top - rect.top
- };
- },
- getViewportOffsetByEvent: function (evt){
- var el = evt.target || evt.srcElement;
- var frameEl = domUtils.getWindow(el).frameElement;
- var offset = {
- left: evt.clientX,
- top: evt.clientY
- };
- if (frameEl && el.ownerDocument !== document) {
- var rect = uiUtils.getClientRect(frameEl);
- offset.left += rect.left;
- offset.top += rect.top;
- }
- return offset;
- },
- setGlobal: function (id, obj){
- root[id] = obj;
- return magic + '["' + id + '"]';
- },
- unsetGlobal: function (id){
- delete root[id];
- },
- copyAttributes: function (tgt, src){
- var attributes = src.attributes;
- var k = attributes.length;
- while (k --) {
- var attrNode = attributes[k];
- if ( attrNode.nodeName != 'style' && attrNode.nodeName != 'class' && (!browser.ie || attrNode.specified) ) {
- tgt.setAttribute(attrNode.nodeName, attrNode.nodeValue);
- }
- }
- if (src.className) {
- domUtils.addClass(tgt,src.className);
- }
- if (src.style.cssText) {
- tgt.style.cssText += ';' + src.style.cssText;
- }
- },
- removeStyle: function (el, styleName){
- if (el.style.removeProperty) {
- el.style.removeProperty(styleName);
- } else if (el.style.removeAttribute) {
- el.style.removeAttribute(styleName);
- } else throw '';
- },
- contains: function (elA, elB){
- return elA && elB && (elA === elB ? false : (
- elA.contains ? elA.contains(elB) :
- elA.compareDocumentPosition(elB) & 16
- ));
- },
- startDrag: function (evt, callbacks,doc){
- var doc = doc || document;
- var startX = evt.clientX;
- var startY = evt.clientY;
- function handleMouseMove(evt){
- var x = evt.clientX - startX;
- var y = evt.clientY - startY;
- callbacks.ondragmove(x, y);
- if (evt.stopPropagation) {
- evt.stopPropagation();
- } else {
- evt.cancelBubble = true;
- }
- }
- if (doc.addEventListener) {
- function handleMouseUp(evt){
- doc.removeEventListener('mousemove', handleMouseMove, true);
- doc.removeEventListener('mouseup', handleMouseMove, true);
- window.removeEventListener('mouseup', handleMouseUp, true);
- callbacks.ondragstop();
- }
- doc.addEventListener('mousemove', handleMouseMove, true);
- doc.addEventListener('mouseup', handleMouseUp, true);
- window.addEventListener('mouseup', handleMouseUp, true);
- evt.preventDefault();
- } else {
- var elm = evt.srcElement;
- elm.setCapture();
- function releaseCaptrue(){
- elm.releaseCapture();
- elm.detachEvent('onmousemove', handleMouseMove);
- elm.detachEvent('onmouseup', releaseCaptrue);
- elm.detachEvent('onlosecaptrue', releaseCaptrue);
- callbacks.ondragstop();
- }
- elm.attachEvent('onmousemove', handleMouseMove);
- elm.attachEvent('onmouseup', releaseCaptrue);
- elm.attachEvent('onlosecaptrue', releaseCaptrue);
- evt.returnValue = false;
- }
- callbacks.ondragstart();
- },
- getFixedLayer: function (){
- var layer = document.getElementById('edui_fixedlayer');
- if (layer == null) {
- layer = document.createElement('div');
- layer.id = 'edui_fixedlayer';
- document.body.appendChild(layer);
- if (browser.ie && browser.version <= 8) {
- layer.style.position = 'absolute';
- bindFixedLayer();
- setTimeout(updateFixedOffset);
- } else {
- layer.style.position = 'fixed';
- }
- layer.style.left = '0';
- layer.style.top = '0';
- layer.style.width = '0';
- layer.style.height = '0';
- }
- return layer;
- },
- makeUnselectable: function (element){
- if (browser.opera || (browser.ie && browser.version < 9)) {
- element.unselectable = 'on';
- if (element.hasChildNodes()) {
- for (var i=0; i<element.childNodes.length; i++) {
- if (element.childNodes[i].nodeType == 1) {
- uiUtils.makeUnselectable(element.childNodes[i]);
- }
- }
- }
- } else {
- if (element.style.MozUserSelect !== undefined) {
- element.style.MozUserSelect = 'none';
- } else if (element.style.WebkitUserSelect !== undefined) {
- element.style.WebkitUserSelect = 'none';
- } else if (element.style.KhtmlUserSelect !== undefined) {
- element.style.KhtmlUserSelect = 'none';
- }
- }
- }
- };
- function updateFixedOffset(){
- var layer = document.getElementById('edui_fixedlayer');
- uiUtils.setViewportOffset(layer, {
- left: 0,
- top: 0
- });
- // layer.style.display = 'none';
- // layer.style.display = 'block';
- //#trace: 1354
- // setTimeout(updateFixedOffset);
- }
- function bindFixedLayer(adjOffset){
- domUtils.on(window, 'scroll', updateFixedOffset);
- domUtils.on(window, 'resize', baidu.editor.utils.defer(updateFixedOffset, 0, true));
- }
- })();
- (function () {
- var utils = baidu.editor.utils,
- uiUtils = baidu.editor.ui.uiUtils,
- EventBase = baidu.editor.EventBase,
- UIBase = baidu.editor.ui.UIBase = function () {
- };
- UIBase.prototype = {
- className:'',
- uiName:'',
- initOptions:function (options) {
- var me = this;
- for (var k in options) {
- me[k] = options[k];
- }
- this.id = this.id || 'edui' + uiUtils.uid();
- },
- initUIBase:function () {
- this._globalKey = utils.unhtml(uiUtils.setGlobal(this.id, this));
- },
- render:function (holder) {
- var html = this.renderHtml();
- var el = uiUtils.createElementByHtml(html);
- //by xuheng 给每个node添加class
- var list = domUtils.getElementsByTagName(el, "*");
- var theme = "edui-" + (this.theme || this.editor.options.theme);
- var layer = document.getElementById('edui_fixedlayer');
- for (var i = 0, node; node = list[i++];) {
- domUtils.addClass(node, theme);
- }
- domUtils.addClass(el, theme);
- if(layer){
- layer.className="";
- domUtils.addClass(layer,theme);
- }
- var seatEl = this.getDom();
- if (seatEl != null) {
- seatEl.parentNode.replaceChild(el, seatEl);
- uiUtils.copyAttributes(el, seatEl);
- } else {
- if (typeof holder == 'string') {
- holder = document.getElementById(holder);
- }
- holder = holder || uiUtils.getFixedLayer();
- domUtils.addClass(holder, theme);
- holder.appendChild(el);
- }
- this.postRender();
- },
- getDom:function (name) {
- if (!name) {
- return document.getElementById(this.id);
- } else {
- return document.getElementById(this.id + '_' + name);
- }
- },
- postRender:function () {
- this.fireEvent('postrender');
- },
- getHtmlTpl:function () {
- return '';
- },
- formatHtml:function (tpl) {
- var prefix = 'edui-' + this.uiName;
- return (tpl
- .replace(/##/g, this.id)
- .replace(/%%-/g, this.uiName ? prefix + '-' : '')
- .replace(/%%/g, (this.uiName ? prefix : '') + ' ' + this.className)
- .replace(/\$\$/g, this._globalKey));
- },
- renderHtml:function () {
- return this.formatHtml(this.getHtmlTpl());
- },
- dispose:function () {
- var box = this.getDom();
- if (box) baidu.editor.dom.domUtils.remove(box);
- uiUtils.unsetGlobal(this.id);
- }
- };
- utils.inherits(UIBase, EventBase);
- })();
- (function (){
- var utils = baidu.editor.utils,
- UIBase = baidu.editor.ui.UIBase,
- Separator = baidu.editor.ui.Separator = function (options){
- this.initOptions(options);
- this.initSeparator();
- };
- Separator.prototype = {
- uiName: 'separator',
- initSeparator: function (){
- this.initUIBase();
- },
- getHtmlTpl: function (){
- return '<div id="##" class="edui-box %%"></div>';
- }
- };
- utils.inherits(Separator, UIBase);
- })();
- ///import core
- ///import uicore
- (function (){
- var utils = baidu.editor.utils,
- domUtils = baidu.editor.dom.domUtils,
- UIBase = baidu.editor.ui.UIBase,
- uiUtils = baidu.editor.ui.uiUtils;
-
- var Mask = baidu.editor.ui.Mask = function (options){
- this.initOptions(options);
- this.initUIBase();
- };
- Mask.prototype = {
- getHtmlTpl: function (){
- return '<div id="##" class="edui-mask %%" onmousedown="return $$._onMouseDown(event, this);"></div>';
- },
- postRender: function (){
- var me = this;
- domUtils.on(window, 'resize', function (){
- setTimeout(function (){
- if (!me.isHidden()) {
- me._fill();
- }
- });
- });
- },
- show: function (zIndex){
- this._fill();
- this.getDom().style.display = '';
- this.getDom().style.zIndex = zIndex;
- },
- hide: function (){
- this.getDom().style.display = 'none';
- this.getDom().style.zIndex = '';
- },
- isHidden: function (){
- return this.getDom().style.display == 'none';
- },
- _onMouseDown: function (){
- return false;
- },
- _fill: function (){
- var el = this.getDom();
- var vpRect = uiUtils.getViewportRect();
- el.style.width = vpRect.width + 'px';
- el.style.height = vpRect.height + 'px';
- }
- };
- utils.inherits(Mask, UIBase);
- })();
- ///import core
- ///import uicore
- (function () {
- var utils = baidu.editor.utils,
- uiUtils = baidu.editor.ui.uiUtils,
- domUtils = baidu.editor.dom.domUtils,
- UIBase = baidu.editor.ui.UIBase,
- Popup = baidu.editor.ui.Popup = function (options){
- this.initOptions(options);
- this.initPopup();
- };
- var allPopups = [];
- function closeAllPopup( evt,el ){
- var newAll = [];
- for ( var i = 0; i < allPopups.length; i++ ) {
- var pop = allPopups[i];
- if (!pop.isHidden()) {
- if (pop.queryAutoHide(el) !== false) {
- if(evt&&/scroll/ig.test(evt.type)&&pop.className=="edui-wordpastepop") return;
- pop.hide();
- }
- }
- }
- }
- Popup.postHide = closeAllPopup;
- var ANCHOR_CLASSES = ['edui-anchor-topleft','edui-anchor-topright',
- 'edui-anchor-bottomleft','edui-anchor-bottomright'];
- Popup.prototype = {
- SHADOW_RADIUS: 5,
- content: null,
- _hidden: false,
- autoRender: true,
- canSideLeft: true,
- canSideUp: true,
- initPopup: function (){
- this.initUIBase();
- allPopups.push( this );
- },
- getHtmlTpl: function (){
- return '<div id="##" class="edui-popup %%">' +
- ' <div id="##_body" class="edui-popup-body">' +
- ' <iframe style="position:absolute;z-index:-1;left:0;top:0;background-color: transparent;" frameborder="0" width="100%" height="100%" src="javascript:"></iframe>' +
- ' <div class="edui-shadow"></div>' +
- ' <div id="##_content" class="edui-popup-content">' +
- this.getContentHtmlTpl() +
- ' </div>' +
- ' </div>' +
- '</div>';
- },
- getContentHtmlTpl: function (){
- if(this.content){
- if (typeof this.content == 'string') {
- return this.content;
- }
- return this.content.renderHtml();
- }else{
- return ''
- }
- },
- _UIBase_postRender: UIBase.prototype.postRender,
- postRender: function (){
- if (this.content instanceof UIBase) {
- this.content.postRender();
- }
- this.fireEvent('postRenderAfter');
- this.hide(true);
- this._UIBase_postRender();
- },
- _doAutoRender: function (){
- if (!this.getDom() && this.autoRender) {
- this.render();
- }
- },
- mesureSize: function (){
- var box = this.getDom('content');
- return uiUtils.getClientRect(box);
- },
- fitSize: function (){
- var popBodyEl = this.getDom('body');
- popBodyEl.style.width = '';
- popBodyEl.style.height = '';
- var size = this.mesureSize();
- popBodyEl.style.width = size.width + 'px';
- popBodyEl.style.height = size.height + 'px';
- return size;
- },
- showAnchor: function ( element, hoz ){
- this.showAnchorRect( uiUtils.getClientRect( element ), hoz );
- },
- showAnchorRect: function ( rect, hoz, adj ){
- this._doAutoRender();
- var vpRect = uiUtils.getViewportRect();
- this._show();
- var popSize = this.fitSize();
- var sideLeft, sideUp, left, top;
- if (hoz) {
- sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width);
- sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height);
- left = (sideLeft ? rect.left - popSize.width : rect.right);
- top = (sideUp ? rect.bottom - popSize.height : rect.top);
- } else {
- sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width);
- sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height);
- left = (sideLeft ? rect.right - popSize.width : rect.left);
- top = (sideUp ? rect.top - popSize.height : rect.bottom);
- }
- var popEl = this.getDom();
- uiUtils.setViewportOffset(popEl, {
- left: left,
- top: top
- });
- domUtils.removeClasses(popEl, ANCHOR_CLASSES);
- popEl.className += ' ' + ANCHOR_CLASSES[(sideUp ? 1 : 0) * 2 + (sideLeft ? 1 : 0)];
- if(this.editor){
- popEl.style.zIndex = this.editor.container.style.zIndex * 1 + 10;
- baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex = popEl.style.zIndex - 1;
- }
- },
- showAt: function (offset) {
- var left = offset.left;
- var top = offset.top;
- var rect = {
- left: left,
- top: top,
- right: left,
- bottom: top,
- height: 0,
- width: 0
- };
- this.showAnchorRect(rect, false, true);
- },
- _show: function (){
- if (this._hidden) {
- var box = this.getDom();
- box.style.display = '';
- this._hidden = false;
- // if (box.setActive) {
- // box.setActive();
- // }
- this.fireEvent('show');
- }
- },
- isHidden: function (){
- return this._hidden;
- },
- show: function (){
- this._doAutoRender();
- this._show();
- },
- hide: function (notNofity){
- if (!this._hidden && this.getDom()) {
- // this.getDom().style.visibility = 'hidden';
- this.getDom().style.display = 'none';
- this._hidden = true;
- if (!notNofity) {
- this.fireEvent('hide');
- }
- }
- },
- queryAutoHide: function (el){
- return !el || !uiUtils.contains(this.getDom(), el);
- }
- };
- utils.inherits(Popup, UIBase);
-
- domUtils.on( document, 'mousedown', function ( evt ) {
- var el = evt.target || evt.srcElement;
- closeAllPopup( evt,el );
- } );
- domUtils.on( window, 'scroll', function (evt,el) {
- closeAllPopup( evt,el );
- } );
- // var lastVpRect = uiUtils.getViewportRect();
- // domUtils.on( window, 'resize', function () {
- // var vpRect = uiUtils.getViewportRect();
- // if (vpRect.width != lastVpRect.width || vpRect.height != lastVpRect.height) {
- // closeAllPopup();
- // }
- // } );
- })();
- ///import core
- ///import uicore
- (function (){
- var utils = baidu.editor.utils,
- UIBase = baidu.editor.ui.UIBase,
- ColorPicker = baidu.editor.ui.ColorPicker = function (options){
- this.initOptions(options);
- this.noColorText = this.noColorText || this.editor.getLang("clearColor");
- this.initUIBase();
- };
- ColorPicker.prototype = {
- getHtmlTpl: function (){
- return genColorPicker(this.noColorText,this.editor);
- },
- _onTableClick: function (evt){
- var tgt = evt.target || evt.srcElement;
- var color = tgt.getAttribute('data-color');
- if (color) {
- this.fireEvent('pickcolor', color);
- }
- },
- _onTableOver: function (evt){
- var tgt = evt.target || evt.srcElement;
- var color = tgt.getAttribute('data-color');
- if (color) {
- this.getDom('preview').style.backgroundColor = color;
- }
- },
- _onTableOut: function (){
- this.getDom('preview').style.backgroundColor = '';
- },
- _onPickNoColor: function (){
- this.fireEvent('picknocolor');
- }
- };
- utils.inherits(ColorPicker, UIBase);
- var COLORS = (
- 'ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,' +
- 'f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,' +
- 'd8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,' +
- 'bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,' +
- 'a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,' +
- '7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,' +
- 'c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,').split(',');
- function genColorPicker(noColorText,editor){
- var html = '<div id="##" class="edui-colorpicker %%">' +
- '<div class="edui-colorpicker-topbar edui-clearfix">' +
- '<div unselectable="on" id="##_preview" class="edui-colorpicker-preview"></div>' +
- '<div unselectable="on" class="edui-colorpicker-nocolor" onclick="$$._onPickNoColor(event, this);">'+ noColorText +'</div>' +
- '</div>' +
- '<table class="edui-box" style="border-collapse: collapse;" onmouseover="$$._onTableOver(event, this);" onmouseout="$$._onTableOut(event, this);" onclick="return $$._onTableClick(event, this);" cellspacing="0" cellpadding="0">' +
- '<tr style="border-bottom: 1px solid #ddd;font-size: 13px;line-height: 25px;color:#39C;padding-top: 2px"><td colspan="10">'+editor.getLang("themeColor")+'</td> </tr>'+
- '<tr class="edui-colorpicker-tablefirstrow" >';
- for (var i=0; i<COLORS.length; i++) {
- if (i && i%10 === 0) {
- html += '</tr>'+(i==60?'<tr style="border-bottom: 1px solid #ddd;font-size: 13px;line-height: 25px;color:#39C;"><td colspan="10">'+editor.getLang("standardColor")+'</td></tr>':'')+'<tr'+(i==60?' class="edui-colorpicker-tablefirstrow"':'')+'>';
- }
- html += i<70 ? '<td style="padding: 0 2px;"><a hidefocus title="'+COLORS[i]+'" onclick="return false;" href="javascript:" unselectable="on" class="edui-box edui-colorpicker-colorcell"' +
- ' data-color="#'+ COLORS[i] +'"'+
- ' style="background-color:#'+ COLORS[i] +';border:solid #ccc;'+
- (i<10 || i>=60?'border-width:1px;':
- i>=10&&i<20?'border-width:1px 1px 0 1px;':
- 'border-width:0 1px 0 1px;')+
- '"' +
- '></a></td>':'';
- }
- html += '</tr></table></div>';
- return html;
- }
- })();
- ///import core
- ///import uicore
- (function (){
- var utils = baidu.editor.utils,
- uiUtils = baidu.editor.ui.uiUtils,
- UIBase = baidu.editor.ui.UIBase;
-
- var TablePicker = baidu.editor.ui.TablePicker = function (options){
- this.initOptions(options);
- this.initTablePicker();
- };
- TablePicker.prototype = {
- defaultNumRows: 10,
- defaultNumCols: 10,
- maxNumRows: 20,
- maxNumCols: 20,
- numRows: 10,
- numCols: 10,
- lengthOfCellSide: 22,
- initTablePicker: function (){
- this.initUIBase();
- },
- getHtmlTpl: function (){
- var me = this;
- return '<div id="##" class="edui-tablepicker %%">' +
- '<div class="edui-tablepicker-body">' +
- '<div class="edui-infoarea">' +
- '<span id="##_label" class="edui-label"></span>' +
- '</div>' +
- '<div class="edui-pickarea"' +
- ' onmousemove="$$._onMouseMove(event, this);"' +
- ' onmouseover="$$._onMouseOver(event, this);"' +
- ' onmouseout="$$._onMouseOut(event, this);"' +
- ' onclick="$$._onClick(event, this);"' +
- '>' +
- '<div id="##_overlay" class="edui-overlay"></div>' +
- '</div>' +
- '</div>' +
- '</div>';
- },
- _UIBase_render: UIBase.prototype.render,
- render: function (holder){
- this._UIBase_render(holder);
- this.getDom('label').innerHTML = '0'+this.editor.getLang("t_row")+' x 0'+this.editor.getLang("t_col");
- },
- _track: function (numCols, numRows){
- var style = this.getDom('overlay').style;
- var sideLen = this.lengthOfCellSide;
- style.width = numCols * sideLen + 'px';
- style.height = numRows * sideLen + 'px';
- var label = this.getDom('label');
- label.innerHTML = numCols +this.editor.getLang("t_col")+' x ' + numRows + this.editor.getLang("t_row");
- this.numCols = numCols;
- this.numRows = numRows;
- },
- _onMouseOver: function (evt, el){
- var rel = evt.relatedTarget || evt.fromElement;
- if (!uiUtils.contains(el, rel) && el !== rel) {
- this.getDom('label').innerHTML = '0'+this.editor.getLang("t_col")+' x 0'+this.editor.getLang("t_row");
- this.getDom('overlay').style.visibility = '';
- }
- },
- _onMouseOut: function (evt, el){
- var rel = evt.relatedTarget || evt.toElement;
- if (!uiUtils.contains(el, rel) && el !== rel) {
- this.getDom('label').innerHTML = '0'+this.editor.getLang("t_col")+' x 0'+this.editor.getLang("t_row");
- this.getDom('overlay').style.visibility = 'hidden';
- }
- },
- _onMouseMove: function (evt, el){
- var style = this.getDom('overlay').style;
- var offset = uiUtils.getEventOffset(evt);
- var sideLen = this.lengthOfCellSide;
- var numCols = Math.ceil(offset.left / sideLen);
- var numRows = Math.ceil(offset.top / sideLen);
- this._track(numCols, numRows);
- },
- _onClick: function (){
- this.fireEvent('picktable', this.numCols, this.numRows);
- }
- };
- utils.inherits(TablePicker, UIBase);
- })();
- (function (){
- var browser = baidu.editor.browser,
- domUtils = baidu.editor.dom.domUtils,
- uiUtils = baidu.editor.ui.uiUtils;
-
- var TPL_STATEFUL = 'onmousedown="$$.Stateful_onMouseDown(event, this);"' +
- ' onmouseup="$$.Stateful_onMouseUp(event, this);"' +
- ( browser.ie ? (
- ' onmouseenter="$$.Stateful_onMouseEnter(event, this);"' +
- ' onmouseleave="$$.Stateful_onMouseLeave(event, this);"' )
- : (
- ' onmouseover="$$.Stateful_onMouseOver(event, this);"' +
- ' onmouseout="$$.Stateful_onMouseOut(event, this);"' ));
-
- baidu.editor.ui.Stateful = {
- alwalysHoverable: false,
- target:null,//目标元素和this指向dom不一样
- Stateful_init: function (){
- this._Stateful_dGetHtmlTpl = this.getHtmlTpl;
- this.getHtmlTpl = this.Stateful_getHtmlTpl;
- },
- Stateful_getHtmlTpl: function (){
- var tpl = this._Stateful_dGetHtmlTpl();
- // 使用function避免$转义
- return tpl.replace(/stateful/g, function (){ return TPL_STATEFUL; });
- },
- Stateful_onMouseEnter: function (evt, el){
- this.target=el;
- if (!this.isDisabled() || this.alwalysHoverable) {
- this.addState('hover');
- this.fireEvent('over');
- }
- },
- Stateful_onMouseLeave: function (evt, el){
- if (!this.isDisabled() || this.alwalysHoverable) {
- this.removeState('hover');
- this.removeState('active');
- this.fireEvent('out');
- }
- },
- Stateful_onMouseOver: function (evt, el){
- var rel = evt.relatedTarget;
- if (!uiUtils.contains(el, rel) && el !== rel) {
- this.Stateful_onMouseEnter(evt, el);
- }
- },
- Stateful_onMouseOut: function (evt, el){
- var rel = evt.relatedTarget;
- if (!uiUtils.contains(el, rel) && el !== rel) {
- this.Stateful_onMouseLeave(evt, el);
- }
- },
- Stateful_onMouseDown: function (evt, el){
- if (!this.isDisabled()) {
- this.addState('active');
- }
- },
- Stateful_onMouseUp: function (evt, el){
- if (!this.isDisabled()) {
- this.removeState('active');
- }
- },
- Stateful_postRender: function (){
- if (this.disabled && !this.hasState('disabled')) {
- this.addState('disabled');
- }
- },
- hasState: function (state){
- return domUtils.hasClass(this.getStateDom(), 'edui-state-' + state);
- },
- addState: function (state){
- if (!this.hasState(state)) {
- this.getStateDom().className += ' edui-state-' + state;
- }
- },
- removeState: function (state){
- if (this.hasState(state)) {
- domUtils.removeClasses(this.getStateDom(), ['edui-state-' + state]);
- }
- },
- getStateDom: function (){
- return this.getDom('state');
- },
- isChecked: function (){
- return this.hasState('checked');
- },
- setChecked: function (checked){
- if (!this.isDisabled() && checked) {
- this.addState('checked');
- } else {
- this.removeState('checked');
- }
- },
- isDisabled: function (){
- return this.hasState('disabled');
- },
- setDisabled: function (disabled){
- if (disabled) {
- this.removeState('hover');
- this.removeState('checked');
- this.removeState('active');
- this.addState('disabled');
- } else {
- this.removeState('disabled');
- }
- }
- };
- })();
- ///import core
- ///import uicore
- ///import ui/stateful.js
- (function (){
- var utils = baidu.editor.utils,
- UIBase = baidu.editor.ui.UIBase,
- Stateful = baidu.editor.ui.Stateful,
- Button = baidu.editor.ui.Button = function (options){
- this.initOptions(options);
- this.initButton();
- };
- Button.prototype = {
- uiName: 'button',
- label: '',
- title: '',
- showIcon: true,
- showText: true,
- initButton: function (){
- this.initUIBase();
- this.Stateful_init();
- },
- getHtmlTpl: function (){
- return '<div id="##" class="edui-box %%">' +
- '<div id="##_state" stateful>' +
- '<div class="%%-wrap"><div id="##_body" unselectable="on" ' + (this.title ? 'title="' + this.title + '"' : '') +
- ' class="%%-body" onmousedown="return false;" onclick="return $$._onClick();">' +
- (this.showIcon ? '<div class="edui-box edui-icon"></div>' : '') +
- (this.showText ? '<div class="edui-box edui-label">' + this.label + '</div>' : '') +
- '</div>' +
- '</div>' +
- '</div></div>';
- },
- postRender: function (){
- this.Stateful_postRender();
- this.setDisabled(this.disabled)
- },
- _onClick: function (){
- if (!this.isDisabled()) {
- this.fireEvent('click');
- }
- }
- };
- utils.inherits(Button, UIBase);
- utils.extend(Button.prototype, Stateful);
- })();
- ///import core
- ///import uicore
- ///import ui/stateful.js
- (function (){
- var utils = baidu.editor.utils,
- uiUtils = baidu.editor.ui.uiUtils,
- domUtils = baidu.editor.dom.domUtils,
- UIBase = baidu.editor.ui.UIBase,
- Stateful = baidu.editor.ui.Stateful,
- SplitButton = baidu.editor.ui.SplitButton = function (options){
- this.initOptions(options);
- this.initSplitButton();
- };
- SplitButton.prototype = {
- popup: null,
- uiName: 'splitbutton',
- title: '',
- initSplitButton: function (){
- this.initUIBase();
- this.Stateful_init();
- var me = this;
- if (this.popup != null) {
- var popup = this.popup;
- this.popup = null;
- this.setPopup(popup);
- }
- },
- _UIBase_postRender: UIBase.prototype.postRender,
- postRender: function (){
- this.Stateful_postRender();
- this._UIBase_postRender();
- },
- setPopup: function (popup){
- if (this.popup === popup) return;
- if (this.popup != null) {
- this.popup.dispose();
- }
- popup.addListener('show', utils.bind(this._onPopupShow, this));
- popup.addListener('hide', utils.bind(this._onPopupHide, this));
- popup.addListener('postrender', utils.bind(function (){
- popup.getDom('body').appendChild(
- uiUtils.createElementByHtml('<div id="' +
- this.popup.id + '_bordereraser" class="edui-bordereraser edui-background" style="width:' +
- (uiUtils.getClientRect(this.getDom()).width - 2) + 'px"></div>')
- );
- popup.getDom().className += ' ' + this.className;
- }, this));
- this.popup = popup;
- },
- _onPopupShow: function (){
- this.addState('opened');
- },
- _onPopupHide: function (){
- this.removeState('opened');
- },
- getHtmlTpl: function (){
- return '<div id="##" class="edui-box %%">' +
- '<div '+ (this.title ? 'title="' + this.title + '"' : '') +' id="##_state" stateful><div class="%%-body">' +
- '<div id="##_button_body" class="edui-box edui-button-body" onclick="$$._onButtonClick(event, this);">' +
- '<div class="edui-box edui-icon"></div>' +
- '</div>' +
- '<div class="edui-box edui-splitborder"></div>' +
- '<div class="edui-box edui-arrow" onclick="$$._onArrowClick();"></div>' +
- '</div></div></div>';
- },
- showPopup: function (){
- // 当popup往上弹出的时候,做特殊处理
- var rect = uiUtils.getClientRect(this.getDom());
- rect.top -= this.popup.SHADOW_RADIUS;
- rect.height += this.popup.SHADOW_RADIUS;
- this.popup.showAnchorRect(rect);
- },
- _onArrowClick: function (event, el){
- if (!this.isDisabled()) {
- this.showPopup();
- }
- },
- _onButtonClick: function (){
- if (!this.isDisabled()) {
- this.fireEvent('buttonclick');
- }
- }
- };
- utils.inherits(SplitButton, UIBase);
- utils.extend(SplitButton.prototype, Stateful, true);
- })();
- ///import core
- ///import uicore
- ///import ui/colorpicker.js
- ///import ui/popup.js
- ///import ui/splitbutton.js
- (function (){
- var utils = baidu.editor.utils,
- uiUtils = baidu.editor.ui.uiUtils,
- ColorPicker = baidu.editor.ui.ColorPicker,
- Popup = baidu.editor.ui.Popup,
- SplitButton = baidu.editor.ui.SplitButton,
- ColorButton = baidu.editor.ui.ColorButton = function (options){
- this.initOptions(options);
- this.initColorButton();
- };
- ColorButton.prototype = {
- initColorButton: function (){
- var me = this;
- this.popup = new Popup({
- content: new ColorPicker({
- noColorText: me.editor.getLang("clearColor"),
- editor:me.editor,
- onpickcolor: function (t, color){
- me._onPickColor(color);
- },
- onpicknocolor: function (t, color){
- me._onPickNoColor(color);
- }
- }),
- editor:me.editor
- });
- this.initSplitButton();
- },
- _SplitButton_postRender: SplitButton.prototype.postRender,
- postRender: function (){
- this._SplitButton_postRender();
- this.getDom('button_body').appendChild(
- uiUtils.createElementByHtml('<div id="' + this.id + '_colorlump" class="edui-colorlump"></div>')
- );
- this.getDom().className += ' edui-colorbutton';
- },
- setColor: function (color){
- this.getDom('colorlump').style.backgroundColor = color;
- this.color = color;
- },
- _onPickColor: function (color){
- if (this.fireEvent('pickcolor', color) !== false) {
- this.setColor(color);
- this.popup.hide();
- }
- },
- _onPickNoColor: function (color){
- if (this.fireEvent('picknocolor') !== false) {
- this.popup.hide();
- }
- }
- };
- utils.inherits(ColorButton, SplitButton);
- })();
- ///import core
- ///import uicore
- ///import ui/popup.js
- ///import ui/tablepicker.js
- ///import ui/splitbutton.js
- (function (){
- var utils = baidu.editor.utils,
- Popup = baidu.editor.ui.Popup,
- TablePicker = baidu.editor.ui.TablePicker,
- SplitButton = baidu.editor.ui.SplitButton,
- TableButton = baidu.editor.ui.TableButton = function (options){
- this.initOptions(options);
- this.initTableButton();
- };
- TableButton.prototype = {
- initTableButton: function (){
- var me = this;
- this.popup = new Popup({
- content: new TablePicker({
- editor:me.editor,
- onpicktable: function (t, numCols, numRows){
- me._onPickTable(numCols, numRows);
- }
- }),
- 'editor':me.editor
- });
- this.initSplitButton();
- },
- _onPickTable: function (numCols, numRows){
- if (this.fireEvent('picktable', numCols, numRows) !== false) {
- this.popup.hide();
- }
- }
- };
- utils.inherits(TableButton, SplitButton);
- })();
- ///import core
- ///import uicore
- (function () {
- var utils = baidu.editor.utils,
- UIBase = baidu.editor.ui.UIBase;
- var AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker = function (options) {
- this.initOptions(options);
- this.initAutoTypeSetPicker();
- };
- AutoTypeSetPicker.prototype = {
- initAutoTypeSetPicker:function () {
- this.initUIBase();
- },
- getHtmlTpl:function () {
- var me = this.editor,
- opt = me.options.autotypeset,
- lang = me.getLang("autoTypeSet");
- return '<div id="##" class="edui-autotypesetpicker %%">' +
- '<div class="edui-autotypesetpicker-body">' +
- '<table >' +
- '<tr><td nowrap colspan="2"><input type="checkbox" name="mergeEmptyline" ' + (opt["mergeEmptyline"] ? "checked" : "" ) + '>' + lang.mergeLine + '</td><td colspan="2"><input type="checkbox" name="removeEmptyline" ' + (opt["removeEmptyline"] ? "checked" : "" ) + '>' + lang.delLine + '</td></tr>' +
- '<tr><td nowrap colspan="2"><input type="checkbox" name="removeClass" ' + (opt["removeClass"] ? "checked" : "" ) + '>' + lang.removeFormat + '</td><td colspan="2"><input type="checkbox" name="indent" ' + (opt["indent"] ? "checked" : "" ) + '>' + lang.indent + '</td></tr>' +
- '<tr><td nowrap colspan="2"><input type="checkbox" name="textAlign" ' + (opt["textAlign"] ? "checked" : "" ) + '>' + lang.alignment + '</td><td colspan="2" id="textAlignValue"><input type="radio" name="textAlignValue" value="left" ' + ((opt["textAlign"] && opt["textAlign"] == "left") ? "checked" : "") + '>' + me.getLang("justifyleft") + '<input type="radio" name="textAlignValue" value="center" ' + ((opt["textAlign"] && opt["textAlign"] == "center") ? "checked" : "") + '>' + me.getLang("justifycenter") + '<input type="radio" name="textAlignValue" value="right" ' + ((opt["textAlign"] && opt["textAlign"] == "right") ? "checked" : "") + '>' + me.getLang("justifyright") + ' </tr>' +
- '<tr><td nowrap colspan="2"><input type="checkbox" name="imageBlockLine" ' + (opt["imageBlockLine"] ? "checked" : "" ) + '>' + lang.imageFloat + '</td>' +
- '<td nowrap colspan="2" id="imageBlockLineValue">' +
- '<input type="radio" name="imageBlockLineValue" value="none" ' + ((opt["imageBlockLine"] && opt["imageBlockLine"] == "none") ? "checked" : "") + '>' + me.getLang("default") +
- '<input type="radio" name="imageBlockLineValue" value="left" ' + ((opt["imageBlockLine"] && opt["imageBlockLine"] == "left") ? "checked" : "") + '>' + me.getLang("justifyleft") +
- '<input type="radio" name="imageBlockLineValue" value="center" ' + ((opt["imageBlockLine"] && opt["imageBlockLine"] == "center") ? "checked" : "") + '>' + me.getLang("justifycenter") +
- '<input type="radio" name="imageBlockLineValue" value="right" ' + ((opt["imageBlockLine"] && opt["imageBlockLine"] == "right") ? "checked" : "") + '>' + me.getLang("justifyright") + '</tr>' +
- '<tr><td nowrap colspan="2"><input type="checkbox" name="clearFontSize" ' + (opt["clearFontSize"] ? "checked" : "" ) + '>' + lang.removeFontsize + '</td><td colspan="2"><input type="checkbox" name="clearFontFamily" ' + (opt["clearFontFamily"] ? "checked" : "" ) + '>' + lang.removeFontFamily + '</td></tr>' +
- '<tr><td nowrap colspan="4"><input type="checkbox" name="removeEmptyNode" ' + (opt["removeEmptyNode"] ? "checked" : "" ) + '>' + lang.removeHtml + '</td></tr>' +
- '<tr><td nowrap colspan="4"><input type="checkbox" name="pasteFilter" ' + (opt["pasteFilter"] ? "checked" : "" ) + '>' + lang.pasteFilter + '</td></tr>' +
- '<tr><td nowrap colspan="4" align="right"><button >' + lang.run + '</button></td></tr>' +
- '</table>' +
- '</div>' +
- '</div>';
- },
- _UIBase_render:UIBase.prototype.render
- };
- utils.inherits(AutoTypeSetPicker, UIBase);
- })();
- ///import core
- ///import uicore
- ///import ui/popup.js
- ///import ui/autotypesetpicker.js
- ///import ui/splitbutton.js
- (function (){
- var utils = baidu.editor.utils,
- Popup = baidu.editor.ui.Popup,
- AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker,
- SplitButton = baidu.editor.ui.SplitButton,
- AutoTypeSetButton = baidu.editor.ui.AutoTypeSetButton = function (options){
- this.initOptions(options);
- this.initAutoTypeSetButton();
- };
- function getPara(me){
- var opt = me.editor.options.autotypeset,
- cont = me.getDom(),
- ipts = domUtils.getElementsByTagName(cont,"input");
- for(var i=ipts.length-1,ipt;ipt=ipts[i--];){
- if(ipt.getAttribute("type")=="checkbox"){
- var attrName = ipt.getAttribute("name");
- opt[attrName] && delete opt[attrName];
- if(ipt.checked){
- var attrValue = document.getElementById(attrName+"Value");
- if(attrValue){
- if(/input/ig.test(attrValue.tagName)){
- opt[attrName] = attrValue.value;
- }else{
- var iptChilds = attrValue.getElementsByTagName("input");
- for(var j=iptChilds.length-1,iptchild;iptchild=iptChilds[j--];){
- if(iptchild.checked){
- opt[attrName] = iptchild.value;
- break;
- }
- }
- }
- }else{
- opt[attrName] = true;
- }
- }
- }
- }
- var selects = domUtils.getElementsByTagName(cont,"select");
- for(var i=0,si;si=selects[i++];){
- var attr = si.getAttribute('name');
- opt[attr] = opt[attr] ? si.value : '';
- }
- me.editor.options.autotypeset = opt;
- }
- AutoTypeSetButton.prototype = {
- initAutoTypeSetButton: function (){
- var me = this;
- this.popup = new Popup({
- //传入配置参数
- content: new AutoTypeSetPicker({editor:me.editor}),
- 'editor':me.editor,
- hide : function(){
- if (!this._hidden && this.getDom()) {
- getPara(this);
- this.getDom().style.display = 'none';
- this._hidden = true;
- this.fireEvent('hide');
- }
- }
- });
- var flag = 0;
- this.popup.addListener('postRenderAfter',function(){
- var popupUI = this;
- if(flag)return;
- var cont = this.getDom(),
- btn = cont.getElementsByTagName('button')[0];
- btn.onclick = function(){
- getPara(popupUI);
- me.editor.execCommand('autotypeset');
- popupUI.hide()
- };
- flag = 1;
- });
- this.initSplitButton();
- }
- };
- utils.inherits(AutoTypeSetButton, SplitButton);
- })();
- ///import core
- ///import uicore
- (function () {
- var utils = baidu.editor.utils,
- Popup = baidu.editor.ui.Popup,
- Stateful = baidu.editor.ui.Stateful,
- UIBase = baidu.editor.ui.UIBase;
- var CellAlignPicker = baidu.editor.ui.CellAlignPicker = function (options) {
- this.initOptions(options);
- this.initCellAlignPicker();
- };
- CellAlignPicker.prototype = {
- initCellAlignPicker:function () {
- this.initUIBase();
- this.Stateful_init();
- },
- getHtmlTpl:function () {
- return '<div id="##" class="edui-cellalignpicker %%">' +
- '<div class="edui-cellalignpicker-body">' +
- '<table onclick="$$._onClick(event);">' +
- '<tr><td index="0" stateful><div class="edui-icon edui-left"></div></td>' +
- '<td index="1" stateful><div class="edui-icon edui-center"></div></td>' +
- '<td index="2" stateful><div class="edui-icon edui-right"></div></td>' +
- '</tr>' +
- '<tr><td index="3" stateful><div class="edui-icon edui-left"></div></td>' +
- '<td index="4" stateful><div class="edui-icon edui-center"></div></td>' +
- '<td index="5" stateful><div class="edui-icon edui-right"></div></td>' +
- '</tr>' +
- '<tr><td index="6" stateful><div class="edui-icon edui-left"></div></td>' +
- '<td index="7" stateful><div class="edui-icon edui-center"></div></td>' +
- '<td index="8" stateful><div class="edui-icon edui-right"></div></td>' +
- '</tr>' +
- '</table>' +
- '</div>' +
- '</div>';
- },
- getStateDom: function (){
- return this.target;
- },
- _onClick: function (evt){
- var target= evt.target || evt.srcElement;
- if(/icon/.test(target.className)){
- this.items[target.parentNode.getAttribute("index")].onclick();
- Popup.postHide(evt);
- }
- },
- _UIBase_render:UIBase.prototype.render
- };
- utils.inherits(CellAlignPicker, UIBase);
- utils.extend(CellAlignPicker.prototype, Stateful,true);
- })();
- ///import core
- ///import uicore
- (function () {
- var utils = baidu.editor.utils,
- Stateful = baidu.editor.ui.Stateful,
- uiUtils = baidu.editor.ui.uiUtils,
- UIBase = baidu.editor.ui.UIBase;
- var PastePicker = baidu.editor.ui.PastePicker = function (options) {
- this.initOptions(options);
- this.initPastePicker();
- };
- PastePicker.prototype = {
- initPastePicker:function () {
- this.initUIBase();
- this.Stateful_init();
- },
- getHtmlTpl:function () {
- return '<div class="edui-pasteicon" onclick="$$._onClick(this)"></div>' +
- '<div class="edui-pastecontainer">' +
- '<div class="edui-title">' + this.editor.getLang("pasteOpt") + '</div>' +
- '<div class="edui-button">' +
- '<div title="' + this.editor.getLang("pasteSourceFormat") + '" onclick="$$.format(false)" stateful>' +
- '<div class="edui-richtxticon"></div></div>' +
- '<div title="' + this.editor.getLang("tagFormat") + '" onclick="$$.format(2)" stateful>' +
- '<div class="edui-tagicon"></div></div>' +
- '<div title="' + this.editor.getLang("pasteTextFormat") + '" onclick="$$.format(true)" stateful>' +
- '<div class="edui-plaintxticon"></div></div>' +
- '</div>' +
- '</div>' +
- '</div>'
- },
- getStateDom:function () {
- return this.target;
- },
- format:function (param) {
- this.editor.ui._isTransfer = true;
- this.editor.fireEvent('pasteTransfer', param);
- },
- _onClick:function (cur) {
- var node = domUtils.getNextDomNode(cur),
- screenHt = uiUtils.getViewportRect().height,
- subPop = uiUtils.getClientRect(node);
- if ((subPop.top + subPop.height) > screenHt)
- node.style.top = (-subPop.height - cur.offsetHeight) + "px";
- else
- node.style.top = "";
- if (/hidden/ig.test(domUtils.getComputedStyle(node, "visibility"))) {
- node.style.visibility = "visible";
- domUtils.addClass(cur, "edui-state-opened");
- } else {
- node.style.visibility = "hidden";
- domUtils.removeClasses(cur, "edui-state-opened")
- }
- },
- _UIBase_render:UIBase.prototype.render
- };
- utils.inherits(PastePicker, UIBase);
- utils.extend(PastePicker.prototype, Stateful, true);
- })();
- (function (){
- var utils = baidu.editor.utils,
- uiUtils = baidu.editor.ui.uiUtils,
- UIBase = baidu.editor.ui.UIBase,
- Toolbar = baidu.editor.ui.Toolbar = function (options){
- this.initOptions(options);
- this.initToolbar();
- };
- Toolbar.prototype = {
- items: null,
- initToolbar: function (){
- this.items = this.items || [];
- this.initUIBase();
- },
- add: function (item){
- this.items.push(item);
- },
- getHtmlTpl: function (){
- var buff = [];
- for (var i=0; i<this.items.length; i++) {
- buff[i] = this.items[i].renderHtml();
- }
- return '<div id="##" class="edui-toolbar %%" onselectstart="return false;" onmousedown="return $$._onMouseDown(event, this);">' +
- buff.join('') +
- '</div>'
- },
- postRender: function (){
- var box = this.getDom();
- for (var i=0; i<this.items.length; i++) {
- this.items[i].postRender();
- }
- uiUtils.makeUnselectable(box);
- },
- _onMouseDown: function (){
- return false;
- }
- };
- utils.inherits(Toolbar, UIBase);
- })();
- ///import core
- ///import uicore
- ///import ui\popup.js
- ///import ui\stateful.js
- (function () {
- var utils = baidu.editor.utils,
- domUtils = baidu.editor.dom.domUtils,
- uiUtils = baidu.editor.ui.uiUtils,
- UIBase = baidu.editor.ui.UIBase,
- Popup = baidu.editor.ui.Popup,
- Stateful = baidu.editor.ui.Stateful,
- CellAlignPicker = baidu.editor.ui.CellAlignPicker,
- Menu = baidu.editor.ui.Menu = function (options) {
- this.initOptions(options);
- this.initMenu();
- };
- var menuSeparator = {
- renderHtml:function () {
- return '<div class="edui-menuitem edui-menuseparator"><div class="edui-menuseparator-inner"></div></div>';
- },
- postRender:function () {
- },
- queryAutoHide:function () {
- return true;
- }
- };
- Menu.prototype = {
- items:null,
- uiName:'menu',
- initMenu:function () {
- this.items = this.items || [];
- this.initPopup();
- this.initItems();
- },
- initItems:function () {
- for (var i = 0; i < this.items.length; i++) {
- var item = this.items[i];
- if (item == '-') {
- this.items[i] = this.getSeparator();
- } else if (!(item instanceof MenuItem)) {
- item.editor = this.editor;
- item.theme = this.editor.options.theme;
- this.items[i] = this.createItem(item);
- }
- }
- },
- getSeparator:function () {
- return menuSeparator;
- },
- createItem:function (item) {
- return new MenuItem(item);
- },
- _Popup_getContentHtmlTpl:Popup.prototype.getContentHtmlTpl,
- getContentHtmlTpl:function () {
- if (this.items.length == 0) {
- return this._Popup_getContentHtmlTpl();
- }
- var buff = [];
- for (var i = 0; i < this.items.length; i++) {
- var item = this.items[i];
- buff[i] = item.renderHtml();
- }
- return ('<div class="%%-body">' + buff.join('') + '</div>');
- },
- _Popup_postRender:Popup.prototype.postRender,
- postRender:function () {
- var me = this;
- for (var i = 0; i < this.items.length; i++) {
- var item = this.items[i];
- item.ownerMenu = this;
- item.postRender();
- }
- domUtils.on(this.getDom(), 'mouseover', function (evt) {
- evt = evt || event;
- var rel = evt.relatedTarget || evt.fromElement;
- var el = me.getDom();
- if (!uiUtils.contains(el, rel) && el !== rel) {
- me.fireEvent('over');
- }
- });
- this._Popup_postRender();
- },
- queryAutoHide:function (el) {
- if (el) {
- if (uiUtils.contains(this.getDom(), el)) {
- return false;
- }
- for (var i = 0; i < this.items.length; i++) {
- var item = this.items[i];
- if (item.queryAutoHide(el) === false) {
- return false;
- }
- }
- }
- },
- clearItems:function () {
- for (var i = 0; i < this.items.length; i++) {
- var item = this.items[i];
- clearTimeout(item._showingTimer);
- clearTimeout(item._closingTimer);
- if (item.subMenu) {
- item.subMenu.destroy();
- }
- }
- this.items = [];
- },
- destroy:function () {
- if (this.getDom()) {
- domUtils.remove(this.getDom());
- }
- this.clearItems();
- },
- dispose:function () {
- this.destroy();
- }
- };
- utils.inherits(Menu, Popup);
- var MenuItem = baidu.editor.ui.MenuItem = function (options) {
- this.initOptions(options);
- this.initUIBase();
- this.Stateful_init();
- if (this.subMenu && !(this.subMenu instanceof Menu)) {
- if (options.className && options.className.indexOf("aligntd") != -1) {
- var me = this;
- this.subMenu = new Popup({
- content:new CellAlignPicker(this.subMenu),
- parentMenu:me,
- editor:me.editor,
- destroy:function () {
- if (this.getDom()) {
- domUtils.remove(this.getDom());
- }
- }
- });
- this.subMenu.addListener("postRenderAfter", function () {
- domUtils.on(this.getDom(), "mouseover", function () {
- me.addState('opened');
- });
- });
- } else {
- this.subMenu = new Menu(this.subMenu);
- }
- }
- };
- MenuItem.prototype = {
- label:'',
- subMenu:null,
- ownerMenu:null,
- uiName:'menuitem',
- alwalysHoverable:true,
- getHtmlTpl:function () {
- return '<div id="##" class="%%" stateful onclick="$$._onClick(event, this);">' +
- '<div class="%%-body">' +
- this.renderLabelHtml() +
- '</div>' +
- '</div>';
- },
- postRender:function () {
- var me = this;
- this.addListener('over', function () {
- me.ownerMenu.fireEvent('submenuover', me);
- if (me.subMenu) {
- me.delayShowSubMenu();
- }
- });
- if (this.subMenu) {
- this.getDom().className += ' edui-hassubmenu';
- this.subMenu.render();
- this.addListener('out', function () {
- me.delayHideSubMenu();
- });
- this.subMenu.addListener('over', function () {
- clearTimeout(me._closingTimer);
- me._closingTimer = null;
- me.addState('opened');
- });
- this.ownerMenu.addListener('hide', function () {
- me.hideSubMenu();
- });
- this.ownerMenu.addListener('submenuover', function (t, subMenu) {
- if (subMenu !== me) {
- me.delayHideSubMenu();
- }
- });
- this.subMenu._bakQueryAutoHide = this.subMenu.queryAutoHide;
- this.subMenu.queryAutoHide = function (el) {
- if (el && uiUtils.contains(me.getDom(), el)) {
- return false;
- }
- return this._bakQueryAutoHide(el);
- };
- }
- this.getDom().style.tabIndex = '-1';
- uiUtils.makeUnselectable(this.getDom());
- this.Stateful_postRender();
- },
- delayShowSubMenu:function () {
- var me = this;
- if (!me.isDisabled()) {
- me.addState('opened');
- clearTimeout(me._showingTimer);
- clearTimeout(me._closingTimer);
- me._closingTimer = null;
- me._showingTimer = setTimeout(function () {
- me.showSubMenu();
- }, 250);
- }
- },
- delayHideSubMenu:function () {
- var me = this;
- if (!me.isDisabled()) {
- me.removeState('opened');
- clearTimeout(me._showingTimer);
- if (!me._closingTimer) {
- me._closingTimer = setTimeout(function () {
- if (!me.hasState('opened')) {
- me.hideSubMenu();
- }
- me._closingTimer = null;
- }, 400);
- }
- }
- },
- renderLabelHtml:function () {
- return '<div class="edui-arrow"></div>' +
- '<div class="edui-box edui-icon"></div>' +
- '<div class="edui-box edui-label %%-label">' + (this.label || '') + '</div>';
- },
- getStateDom:function () {
- return this.getDom();
- },
- queryAutoHide:function (el) {
- if (this.subMenu && this.hasState('opened')) {
- return this.subMenu.queryAutoHide(el);
- }
- },
- _onClick:function (event, this_) {
- if (this.hasState('disabled')) return;
- if (this.fireEvent('click', event, this_) !== false) {
- if (this.subMenu) {
- this.showSubMenu();
- } else {
- Popup.postHide(event);
- }
- }
- },
- showSubMenu:function () {
- var rect = uiUtils.getClientRect(this.getDom());
- rect.right -= 5;
- rect.left += 2;
- rect.width -= 7;
- rect.top -= 4;
- rect.bottom += 4;
- rect.height += 8;
- this.subMenu.showAnchorRect(rect, true, true);
- },
- hideSubMenu:function () {
- this.subMenu.hide();
- }
- };
- utils.inherits(MenuItem, UIBase);
- utils.extend(MenuItem.prototype, Stateful, true);
- })();
- ///import core
- ///import uicore
- ///import ui/menu.js
- ///import ui/splitbutton.js
- (function (){
- // todo: menu和item提成通用list
- var utils = baidu.editor.utils,
- uiUtils = baidu.editor.ui.uiUtils,
- Menu = baidu.editor.ui.Menu,
- SplitButton = baidu.editor.ui.SplitButton,
- Combox = baidu.editor.ui.Combox = function (options){
- this.initOptions(options);
- this.initCombox();
- };
- Combox.prototype = {
- uiName: 'combox',
- initCombox: function (){
- var me = this;
- this.items = this.items || [];
- for (var i=0; i<this.items.length; i++) {
- var item = this.items[i];
- item.uiName = 'listitem';
- item.index = i;
- item.onclick = function (){
- me.selectByIndex(this.index);
- };
- }
- this.popup = new Menu({
- items: this.items,
- uiName: 'list',
- editor:this.editor
- });
- this.initSplitButton();
- },
- _SplitButton_postRender: SplitButton.prototype.postRender,
- postRender: function (){
- this._SplitButton_postRender();
- this.setLabel(this.label || '');
- this.setValue(this.initValue || '');
- },
- showPopup: function (){
- var rect = uiUtils.getClientRect(this.getDom());
- rect.top += 1;
- rect.bottom -= 1;
- rect.height -= 2;
- this.popup.showAnchorRect(rect);
- },
- getValue: function (){
- return this.value;
- },
- setValue: function (value){
- var index = this.indexByValue(value);
- if (index != -1) {
- this.selectedIndex = index;
- this.setLabel(this.items[index].label);
- this.value = this.items[index].value;
- } else {
- this.selectedIndex = -1;
- this.setLabel(this.getLabelForUnknowValue(value));
- this.value = value;
- }
- },
- setLabel: function (label){
- this.getDom('button_body').innerHTML = label;
- this.label = label;
- },
- getLabelForUnknowValue: function (value){
- return value;
- },
- indexByValue: function (value){
- for (var i=0; i<this.items.length; i++) {
- if (value == this.items[i].value) {
- return i;
- }
- }
- return -1;
- },
- getItem: function (index){
- return this.items[index];
- },
- selectByIndex: function (index){
- if (index < this.items.length && this.fireEvent('select', index) !== false) {
- this.selectedIndex = index;
- this.value = this.items[index].value;
- this.setLabel(this.items[index].label);
- }
- }
- };
- utils.inherits(Combox, SplitButton);
- })();
- ///import core
- ///import uicore
- ///import ui/mask.js
- ///import ui/button.js
- (function (){
- var utils = baidu.editor.utils,
- domUtils = baidu.editor.dom.domUtils,
- uiUtils = baidu.editor.ui.uiUtils,
- Mask = baidu.editor.ui.Mask,
- UIBase = baidu.editor.ui.UIBase,
- Button = baidu.editor.ui.Button,
- Dialog = baidu.editor.ui.Dialog = function (options){
- this.initOptions(utils.extend({
- autoReset: true,
- draggable: true,
- onok: function (){},
- oncancel: function (){},
- onclose: function (t, ok){
- return ok ? this.onok() : this.oncancel();
- }
- },options));
- this.initDialog();
- };
- var modalMask;
- var dragMask;
- Dialog.prototype = {
- draggable: false,
- uiName: 'dialog',
- initDialog: function (){
- var me = this,
- theme=this.editor.options.theme;
- this.initUIBase();
- this.modalMask = (modalMask || (modalMask = new Mask({
- className: 'edui-dialog-modalmask',
- theme:theme
- })));
- this.dragMask = (dragMask || (dragMask = new Mask({
- className: 'edui-dialog-dragmask',
- theme:theme
- })));
- this.closeButton = new Button({
- className: 'edui-dialog-closebutton',
- title: me.closeDialog,
- theme:theme,
- onclick: function (){
- me.close(false);
- }
- });
- if (this.buttons) {
- for (var i=0; i<this.buttons.length; i++) {
- if (!(this.buttons[i] instanceof Button)) {
- this.buttons[i] = new Button(this.buttons[i]);
- }
- }
- }
- },
- fitSize: function (){
- var popBodyEl = this.getDom('body');
- // if (!(baidu.editor.browser.ie && baidu.editor.browser.version == 7)) {
- // uiUtils.removeStyle(popBodyEl, 'width');
- // uiUtils.removeStyle(popBodyEl, 'height');
- // }
- var size = this.mesureSize();
- popBodyEl.style.width = size.width + 'px';
- popBodyEl.style.height = size.height + 'px';
- return size;
- },
- safeSetOffset: function (offset){
- var me = this;
- var el = me.getDom();
- var vpRect = uiUtils.getViewportRect();
- var rect = uiUtils.getClientRect(el);
- var left = offset.left;
- if (left + rect.width > vpRect.right) {
- left = vpRect.right - rect.width;
- }
- var top = offset.top;
- if (top + rect.height > vpRect.bottom) {
- top = vpRect.bottom - rect.height;
- }
- el.style.left = Math.max(left, 0) + 'px';
- el.style.top = Math.max(top, 0) + 'px';
- },
- showAtCenter: function (){
- this.getDom().style.display = '';
- var vpRect = uiUtils.getViewportRect();
- var popSize = this.fitSize();
- var titleHeight = this.getDom('titlebar').offsetHeight | 0;
- var left = vpRect.width / 2 - popSize.width / 2;
- var top = vpRect.height / 2 - (popSize.height - titleHeight) / 2 - titleHeight;
- var popEl = this.getDom();
- this.safeSetOffset({
- left: Math.max(left | 0, 0),
- top: Math.max(top | 0, 0)
- });
- if (!domUtils.hasClass(popEl, 'edui-state-centered')) {
- popEl.className += ' edui-state-centered';
- }
- this._show();
- },
- getContentHtml: function (){
- var contentHtml = '';
- if (typeof this.content == 'string') {
- contentHtml = this.content;
- } else if (this.iframeUrl) {
- contentHtml = '<span id="'+ this.id +'_contmask" class="dialogcontmask"></span><iframe id="'+ this.id +
- '_iframe" class="%%-iframe" height="100%" width="100%" frameborder="0" src="'+ this.iframeUrl +'"></iframe>';
- }
- return contentHtml;
- },
- getHtmlTpl: function (){
- var footHtml = '';
- if (this.buttons) {
- var buff = [];
- for (var i=0; i<this.buttons.length; i++) {
- buff[i] = this.buttons[i].renderHtml();
- }
- footHtml = '<div class="%%-foot">' +
- '<div id="##_buttons" class="%%-buttons">' + buff.join('') + '</div>' +
- '</div>';
- }
- return '<div id="##" class="%%"><div class="%%-wrap"><div id="##_body" class="%%-body">' +
- '<div class="%%-shadow"></div>' +
- '<div id="##_titlebar" class="%%-titlebar">' +
- '<div class="%%-draghandle" onmousedown="$$._onTitlebarMouseDown(event, this);">' +
- '<span class="%%-caption">' + (this.title || '') + '</span>' +
- '</div>' +
- this.closeButton.renderHtml() +
- '</div>' +
- '<div id="##_content" class="%%-content">'+ ( this.autoReset ? '' : this.getContentHtml()) +'</div>' +
- footHtml +
- '</div></div></div>';
- },
- postRender: function (){
- // todo: 保持居中/记住上次关闭位置选项
- if (!this.modalMask.getDom()) {
- this.modalMask.render();
- this.modalMask.hide();
- }
- if (!this.dragMask.getDom()) {
- this.dragMask.render();
- this.dragMask.hide();
- }
- var me = this;
- this.addListener('show', function (){
- me.modalMask.show(this.getDom().style.zIndex - 2);
- });
- this.addListener('hide', function (){
- me.modalMask.hide();
- });
- if (this.buttons) {
- for (var i=0; i<this.buttons.length; i++) {
- this.buttons[i].postRender();
- }
- }
- domUtils.on(window, 'resize', function (){
- setTimeout(function (){
- if (!me.isHidden()) {
- me.safeSetOffset(uiUtils.getClientRect(me.getDom()));
- }
- });
- });
- this._hide();
- },
- mesureSize: function (){
- var body = this.getDom('body');
- var width = uiUtils.getClientRect(this.getDom('content')).width;
- var dialogBodyStyle = body.style;
- dialogBodyStyle.width = width;
- return uiUtils.getClientRect(body);
- },
- _onTitlebarMouseDown: function (evt, el){
- if (this.draggable) {
- var rect;
- var vpRect = uiUtils.getViewportRect();
- var me = this;
- uiUtils.startDrag(evt, {
- ondragstart: function (){
- rect = uiUtils.getClientRect(me.getDom());
- me.getDom('contmask').style.visibility = 'visible';
- me.dragMask.show(me.getDom().style.zIndex - 1);
- },
- ondragmove: function (x, y){
- var left = rect.left + x;
- var top = rect.top + y;
- me.safeSetOffset({
- left: left,
- top: top
- });
- },
- ondragstop: function (){
- me.getDom('contmask').style.visibility = 'hidden';
- domUtils.removeClasses(me.getDom(), ['edui-state-centered']);
- me.dragMask.hide();
- }
- });
- }
- },
- reset: function (){
- this.getDom('content').innerHTML = this.getContentHtml();
- },
- _show: function (){
- if (this._hidden) {
- this.getDom().style.display = '';
- //要高过编辑器的zindxe
- this.editor.container.style.zIndex && (this.getDom().style.zIndex = this.editor.container.style.zIndex * 1 + 10);
- this._hidden = false;
- this.fireEvent('show');
- baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex = this.getDom().style.zIndex - 4;
- }
- },
- isHidden: function (){
- return this._hidden;
- },
- _hide: function (){
- if (!this._hidden) {
- this.getDom().style.display = 'none';
- this.getDom().style.zIndex = '';
- this._hidden = true;
- this.fireEvent('hide');
- }
- },
- open: function (){
- if (this.autoReset) {
- //有可能还没有渲染
- try{
- this.reset();
- }catch(e){
- this.render();
- this.open()
- }
- }
- this.showAtCenter();
- if (this.iframeUrl) {
- try {
- this.getDom('iframe').focus();
- } catch(ex){}
- }
- },
- _onCloseButtonClick: function (evt, el){
- this.close(false);
- },
- close: function (ok){
- if (this.fireEvent('close', ok) !== false) {
- this._hide();
- }
- }
- };
- utils.inherits(Dialog, UIBase);
- })();
- ///import core
- ///import uicore
- ///import ui/menu.js
- ///import ui/splitbutton.js
- (function (){
- var utils = baidu.editor.utils,
- Menu = baidu.editor.ui.Menu,
- SplitButton = baidu.editor.ui.SplitButton,
- MenuButton = baidu.editor.ui.MenuButton = function (options){
- this.initOptions(options);
- this.initMenuButton();
- };
- MenuButton.prototype = {
- initMenuButton: function (){
- var me = this;
- this.uiName = "menubutton";
- this.popup = new Menu({
- items: me.items,
- className: me.className,
- editor:me.editor
- });
- this.popup.addListener('show', function (){
- var list = this;
- for (var i=0; i<list.items.length; i++) {
- list.items[i].removeState('checked');
- if (list.items[i].value == me._value) {
- list.items[i].addState('checked');
- this.value = me._value;
- }
- }
- });
- this.initSplitButton();
- },
- setValue : function(value){
- this._value = value;
- }
-
- };
- utils.inherits(MenuButton, SplitButton);
- })();
- //ui跟编辑器的适配層
- //那个按钮弹出是dialog,是下拉筐等都是在这个js中配置
- //自己写的ui也要在这里配置,放到baidu.editor.ui下边,当编辑器实例化的时候会根据editor_config中的toolbars找到相应的进行实例化
- (function () {
- var utils = baidu.editor.utils;
- var editorui = baidu.editor.ui;
- var _Dialog = editorui.Dialog;
- editorui.buttons={};
- editorui.Dialog = function (options) {
- var dialog = new _Dialog(options);
- dialog.addListener('hide', function () {
- if (dialog.editor) {
- var editor = dialog.editor;
- try {
- if (browser.gecko) {
- var y = editor.window.scrollY,
- x = editor.window.scrollX;
- editor.body.focus();
- editor.window.scrollTo(x, y);
- } else {
- editor.focus();
- }
- } catch (ex) {
- }
- }
- });
- return dialog;
- };
- var iframeUrlMap = {
- 'anchor':'~/dialogs/anchor/anchor.html',
- 'insertimage':'~/dialogs/image/image.html',
- 'link':'~/dialogs/link/link.html',
- 'spechars':'~/dialogs/spechars/spechars.html',
- 'searchreplace':'~/dialogs/searchreplace/searchreplace.html',
- 'map':'~/dialogs/map/map.html',
- 'gmap':'~/dialogs/gmap/gmap.html',
- 'insertvideo':'~/dialogs/video/video.html',
- 'help':'~/dialogs/help/help.html',
- 'highlightcode':'~/dialogs/highlightcode/highlightcode.html',
- 'emotion':'~/dialogs/emotion/emotion.html',
- 'wordimage':'~/dialogs/wordimage/wordimage.html',
- 'attachment':'~/dialogs/attachment/attachment.html',
- 'insertframe':'~/dialogs/insertframe/insertframe.html',
- 'edittip':'~/dialogs/table/edittip.html',
- 'edittable':'~/dialogs/table/edittable.html',
- 'edittd':'~/dialogs/table/edittd.html',
- 'webapp':'~/dialogs/webapp/webapp.html',
- 'snapscreen':'~/dialogs/snapscreen/snapscreen.html',
- 'scrawl':'~/dialogs/scrawl/scrawl.html',
- 'music':'~/dialogs/music/music.html',
- 'template':'~/dialogs/template/template.html',
- 'background':'~/dialogs/background/background.html'
- };
- //为工具栏添加按钮,以下都是统一的按钮触发命令,所以写在一起
- var btnCmds = ['undo', 'redo', 'formatmatch',
- 'bold', 'italic', 'underline', 'touppercase', 'tolowercase',
- 'strikethrough', 'subscript', 'superscript', 'source', 'indent', 'outdent',
- 'blockquote', 'pasteplain', 'pagebreak',
- 'selectall', 'print', 'preview', 'horizontal', 'removeformat', 'time', 'date', 'unlink',
- 'insertparagraphbeforetable', 'insertrow', 'insertcol', 'mergeright', 'mergedown', 'deleterow',
- 'deletecol', 'splittorows', 'splittocols', 'splittocells', 'mergecells', 'deletetable','signset'];
- for (var i = 0, ci; ci = btnCmds[i++];) {
- ci = ci.toLowerCase();
- editorui[ci] = function (cmd) {
- return function (editor) {
- var ui = new editorui.Button({
- className:'edui-for-' + cmd,
- title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '',
- onclick:function () {
- editor.execCommand(cmd);
- },
- theme:editor.options.theme,
- showText:false
- });
- editorui.buttons[cmd]=ui;
- editor.addListener('selectionchange', function (type, causeByUi, uiReady) {
- var state = editor.queryCommandState(cmd);
- if (state == -1) {
- ui.setDisabled(true);
- ui.setChecked(false);
- } else {
- if (!uiReady) {
- ui.setDisabled(false);
- ui.setChecked(state);
- }
- }
- });
- return ui;
- };
- }(ci);
- }
- //清除文档
- editorui.cleardoc = function (editor) {
- var ui = new editorui.Button({
- className:'edui-for-cleardoc',
- title:editor.options.labelMap.cleardoc || editor.getLang("labelMap.cleardoc") || '',
- theme:editor.options.theme,
- onclick:function () {
- if (confirm(editor.getLang("confirmClear"))) {
- editor.execCommand('cleardoc');
- }
- }
- });
- editorui.buttons["cleardoc"]=ui;
- editor.addListener('selectionchange', function () {
- ui.setDisabled(editor.queryCommandState('cleardoc') == -1);
- });
- return ui;
- };
- //排版,图片排版,文字方向
- var typeset = {
- 'justify':['left', 'right', 'center', 'justify'],
- 'imagefloat':['none', 'left', 'center', 'right'],
- 'directionality':['ltr', 'rtl']
- };
- for (var p in typeset) {
- (function (cmd, val) {
- for (var i = 0, ci; ci = val[i++];) {
- (function (cmd2) {
- editorui[cmd.replace('float', '') + cmd2] = function (editor) {
- var ui = new editorui.Button({
- className:'edui-for-' + cmd.replace('float', '') + cmd2,
- title:editor.options.labelMap[cmd.replace('float', '') + cmd2] || editor.getLang("labelMap." + cmd.replace('float', '') + cmd2) || '',
- theme:editor.options.theme,
- onclick:function () {
- editor.execCommand(cmd, cmd2);
- }
- });
- editorui.buttons[cmd]=ui;
- editor.addListener('selectionchange', function (type, causeByUi, uiReady) {
- ui.setDisabled(editor.queryCommandState(cmd) == -1);
- ui.setChecked(editor.queryCommandValue(cmd) == cmd2 && !uiReady);
- });
- return ui;
- };
- })(ci)
- }
- })(p, typeset[p])
- }
- //字体颜色和背景颜色
- for (var i = 0, ci; ci = ['backcolor', 'forecolor'][i++];) {
- editorui[ci] = function (cmd) {
- return function (editor) {
- var ui = new editorui.ColorButton({
- className:'edui-for-' + cmd,
- color:'default',
- title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '',
- editor:editor,
- onpickcolor:function (t, color) {
- editor.execCommand(cmd, color);
- },
- onpicknocolor:function () {
- editor.execCommand(cmd, 'default');
- this.setColor('transparent');
- this.color = 'default';
- },
- onbuttonclick:function () {
- editor.execCommand(cmd, this.color);
- }
- });
- editorui.buttons[cmd]=ui;
- editor.addListener('selectionchange', function () {
- ui.setDisabled(editor.queryCommandState(cmd) == -1);
- });
- return ui;
- };
- }(ci);
- }
- var dialogBtns = {
- noOk:['searchreplace', 'help', 'spechars', 'webapp'],
- ok:['attachment', 'anchor', 'link', 'insertimage', 'map', 'gmap', 'insertframe', 'wordimage',
- 'insertvideo', 'highlightcode', 'insertframe','edittip','edittable', 'edittd','scrawl', 'template','music', 'background']
- };
- for (var p in dialogBtns) {
- (function (type, vals) {
- for (var i = 0, ci; ci = vals[i++];) {
- //todo opera下存在问题
- if (browser.opera && ci === "searchreplace") {
- continue;
- }
- (function (cmd) {
- editorui[cmd] = function (editor, iframeUrl, title) {
- iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd];
- title = editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '';
- var dialog;
- //没有iframeUrl不创建dialog
- if (iframeUrl) {
- dialog = new editorui.Dialog(utils.extend({
- iframeUrl:editor.ui.mapUrl(iframeUrl),
- editor:editor,
- className:'edui-for-' + cmd,
- title:title,
- closeDialog:editor.getLang("closeDialog")
- }, type == 'ok' ? {
- buttons:[
- {
- className:'edui-okbutton',
- label:editor.getLang("ok"),
- editor:editor,
- onclick:function () {
- dialog.close(true);
- }
- },
- {
- className:'edui-cancelbutton',
- label:editor.getLang("cancel"),
- editor:editor,
- onclick:function () {
- dialog.close(false);
- }
- }
- ]
- } : {}));
- editor.ui._dialogs[cmd + "Dialog"] = dialog;
- }
- var ui = new editorui.Button({
- className:'edui-for-' + cmd,
- title:title,
- onclick:function () {
- if (dialog) {
- switch (cmd) {
- case "wordimage":
- editor.execCommand("wordimage", "word_img");
- if (editor.word_img) {
- dialog.render();
- dialog.open();
- }
- break;
- case "scrawl":
- if (editor.queryCommandState("scrawl") != -1) {
- dialog.render();
- dialog.open();
- }
- break;
- default:
- dialog.render();
- dialog.open();
- }
- }
- },
- theme:editor.options.theme,
- disabled:cmd == 'scrawl' && editor.queryCommandState("scrawl") == -1
- });
- editorui.buttons[cmd]=ui;
- editor.addListener('selectionchange', function () {
- //只存在于右键菜单而无工具栏按钮的ui不需要检测状态
- var unNeedCheckState = {'edittable':1};
- if (cmd in unNeedCheckState)return;
- var state = editor.queryCommandState(cmd);
- if (ui.getDom()) {
- ui.setDisabled(state == -1);
- ui.setChecked(state);
- }
- });
- return ui;
- };
- })(ci.toLowerCase())
- }
- })(p, dialogBtns[p])
- }
- editorui.snapscreen = function (editor, iframeUrl, title) {
- title = editor.options.labelMap['snapscreen'] || editor.getLang("labelMap.snapscreen") || '';
- var ui = new editorui.Button({
- className:'edui-for-snapscreen',
- title:title,
- onclick:function () {
- editor.execCommand("snapscreen");
- },
- theme:editor.options.theme
- });
- editorui.buttons['snapscreen']=ui;
- iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})["snapscreen"] || iframeUrlMap["snapscreen"];
- if (iframeUrl) {
- var dialog = new editorui.Dialog({
- iframeUrl:editor.ui.mapUrl(iframeUrl),
- editor:editor,
- className:'edui-for-snapscreen',
- title:title,
- buttons:[
- {
- className:'edui-okbutton',
- label:editor.getLang("ok"),
- editor:editor,
- onclick:function () {
- dialog.close(true);
- }
- },
- {
- className:'edui-cancelbutton',
- label:editor.getLang("cancel"),
- editor:editor,
- onclick:function () {
- dialog.close(false);
- }
- }
- ]
- });
- dialog.render();
- editor.ui._dialogs["snapscreenDialog"] = dialog;
- }
- editor.addListener('selectionchange', function () {
- ui.setDisabled(editor.queryCommandState('snapscreen') == -1);
- });
- return ui;
- };
- editorui.fontfamily = function (editor, list, title) {
- list = editor.options['fontfamily'] || [];
- title = editor.options.labelMap['fontfamily'] || editor.getLang("labelMap.fontfamily") || '';
- if(!list.length) return;
- for (var i = 0, ci, items = []; ci = list[i]; i++) {
- var langLabel = editor.getLang('fontfamily')[ci.name] || "";
- (function (key, val) {
- items.push({
- label:key,
- value:val,
- theme:editor.options.theme,
- renderLabelHtml:function () {
- return '<div class="edui-label %%-label" style="font-family:' +
- utils.unhtml(this.value) + '">' + (this.label || '') + '</div>';
- }
- });
- })(ci.label || langLabel, ci.val)
- }
- var ui = new editorui.Combox({
- editor:editor,
- items:items,
- onselect:function (t, index) {
- editor.execCommand('FontFamily', this.items[index].value);
- },
- onbuttonclick:function () {
- this.showPopup();
- },
- title:title,
- initValue:title,
- className:'edui-for-fontfamily',
- indexByValue:function (value) {
- if (value) {
- for (var i = 0, ci; ci = this.items[i]; i++) {
- if (ci.value.indexOf(value) != -1)
- return i;
- }
- }
- return -1;
- }
- });
- editorui.buttons['fontfamily']=ui;
- editor.addListener('selectionchange', function (type, causeByUi, uiReady) {
- if (!uiReady) {
- var state = editor.queryCommandState('FontFamily');
- if (state == -1) {
- ui.setDisabled(true);
- } else {
- ui.setDisabled(false);
- var value = editor.queryCommandValue('FontFamily');
- //trace:1871 ie下从源码模式切换回来时,字体会带单引号,而且会有逗号
- value && (value = value.replace(/['"]/g, '').split(',')[0]);
- ui.setValue(value);
- }
- }
- });
- return ui;
- };
- editorui.fontsize = function (editor, list, title) {
- title = editor.options.labelMap['fontsize'] || editor.getLang("labelMap.fontsize") || '';
- list = list || editor.options['fontsize'] || [];
- if(!list.length) return;
- var items = [];
- for (var i = 0; i < list.length; i++) {
- var size = list[i] + 'px';
- items.push({
- label:size,
- value:size,
- theme:editor.options.theme,
- renderLabelHtml:function () {
- return '<div class="edui-label %%-label" style="line-height:1;font-size:' +
- this.value + '">' + (this.label || '') + '</div>';
- }
- });
- }
- var ui = new editorui.Combox({
- editor:editor,
- items:items,
- title:title,
- initValue:title,
- onselect:function (t, index) {
- editor.execCommand('FontSize', this.items[index].value);
- },
- onbuttonclick:function () {
- this.showPopup();
- },
- className:'edui-for-fontsize'
- });
- editorui.buttons['fontsize']=ui;
- editor.addListener('selectionchange', function (type, causeByUi, uiReady) {
- if (!uiReady) {
- var state = editor.queryCommandState('FontSize');
- if (state == -1) {
- ui.setDisabled(true);
- } else {
- ui.setDisabled(false);
- ui.setValue(editor.queryCommandValue('FontSize'));
- }
- }
- });
- return ui;
- };
- editorui.paragraph = function (editor, list, title) {
- title = editor.options.labelMap['paragraph'] || editor.getLang("labelMap.paragraph") || '';
- list = editor.options['paragraph'] || [];
- if(utils.isEmptyObject(list)) return;
- var items = [];
- for (var i in list) {
- items.push({
- value:i,
- label:list[i] || editor.getLang("paragraph")[i],
- theme:editor.options.theme,
- renderLabelHtml:function () {
- return '<div class="edui-label %%-label"><span class="edui-for-' + this.value + '">' + (this.label || '') + '</span></div>';
- }
- })
- }
- var ui = new editorui.Combox({
- editor:editor,
- items:items,
- title:title,
- initValue:title,
- className:'edui-for-paragraph',
- onselect:function (t, index) {
- editor.execCommand('Paragraph', this.items[index].value);
- },
- onbuttonclick:function () {
- this.showPopup();
- }
- });
- editorui.buttons['paragraph']=ui;
- editor.addListener('selectionchange', function (type, causeByUi, uiReady) {
- if (!uiReady) {
- var state = editor.queryCommandState('Paragraph');
- if (state == -1) {
- ui.setDisabled(true);
- } else {
- ui.setDisabled(false);
- var value = editor.queryCommandValue('Paragraph');
- var index = ui.indexByValue(value);
- if (index != -1) {
- ui.setValue(value);
- } else {
- ui.setValue(ui.initValue);
- }
- }
- }
- });
- return ui;
- };
- //自定义标题
- editorui.customstyle = function (editor) {
- var list = editor.options['customstyle'] || [],
- title = editor.options.labelMap['customstyle'] || editor.getLang("labelMap.customstyle") || '';
- if (!list.length)return;
- var langCs = editor.getLang('customstyle');
- for (var i = 0, items = [], t; t = list[i++];) {
- (function (t) {
- var ck = {};
- ck.label = t.label ? t.label : langCs[t.name];
- ck.style = t.style;
- ck.className = t.className;
- ck.tag = t.tag;
- items.push({
- label:ck.label,
- value:ck,
- theme:editor.options.theme,
- renderLabelHtml:function () {
- return '<div class="edui-label %%-label">' + '<' + ck.tag + ' ' + (ck.className ? ' class="' + ck.className + '"' : "")
- + (ck.style ? ' style="' + ck.style + '"' : "") + '>' + ck.label + "<\/" + ck.tag + ">"
- + '</div>';
- }
- });
- })(t);
- }
- var ui = new editorui.Combox({
- editor:editor,
- items:items,
- title:title,
- initValue:title,
- className:'edui-for-customstyle',
- onselect:function (t, index) {
- editor.execCommand('customstyle', this.items[index].value);
- },
- onbuttonclick:function () {
- this.showPopup();
- },
- indexByValue:function (value) {
- for (var i = 0, ti; ti = this.items[i++];) {
- if (ti.label == value) {
- return i - 1
- }
- }
- return -1;
- }
- });
- editorui.buttons['customstyle']=ui;
- editor.addListener('selectionchange', function (type, causeByUi, uiReady) {
- if (!uiReady) {
- var state = editor.queryCommandState('customstyle');
- if (state == -1) {
- ui.setDisabled(true);
- } else {
- ui.setDisabled(false);
- var value = editor.queryCommandValue('customstyle');
- var index = ui.indexByValue(value);
- if (index != -1) {
- ui.setValue(value);
- } else {
- ui.setValue(ui.initValue);
- }
- }
- }
- });
- return ui;
- };
- editorui.inserttable = function (editor, iframeUrl, title) {
- title = editor.options.labelMap['inserttable'] || editor.getLang("labelMap.inserttable") || '';
- var ui = new editorui.TableButton({
- editor:editor,
- title:title,
- className:'edui-for-inserttable',
- onpicktable:function (t, numCols, numRows) {
- editor.execCommand('InsertTable', {numRows:numRows, numCols:numCols, border:1});
- },
- onbuttonclick:function () {
- this.showPopup();
- }
- });
- editorui.buttons['inserttable']=ui;
- editor.addListener('selectionchange', function () {
- ui.setDisabled(editor.queryCommandState('inserttable') == -1);
- });
- return ui;
- };
- editorui.lineheight = function (editor) {
- var val = editor.options.lineheight || [];
- if(!val.length)return;
- for (var i = 0, ci, items = []; ci = val[i++];) {
- items.push({
- //todo:写死了
- label:ci,
- value:ci,
- theme:editor.options.theme,
- onclick:function () {
- editor.execCommand("lineheight", this.value);
- }
- })
- }
- var ui = new editorui.MenuButton({
- editor:editor,
- className:'edui-for-lineheight',
- title:editor.options.labelMap['lineheight'] || editor.getLang("labelMap.lineheight") || '',
- items:items,
- onbuttonclick:function () {
- var value = editor.queryCommandValue('LineHeight') || this.value;
- editor.execCommand("LineHeight", value);
- }
- });
- editorui.buttons['lineheight']=ui;
- editor.addListener('selectionchange', function () {
- var state = editor.queryCommandState('LineHeight');
- if (state == -1) {
- ui.setDisabled(true);
- } else {
- ui.setDisabled(false);
- var value = editor.queryCommandValue('LineHeight');
- value && ui.setValue((value + '').replace(/cm/, ''));
- ui.setChecked(state)
- }
- });
- return ui;
- };
- var rowspacings = ['top', 'bottom'];
- for (var r = 0, ri; ri = rowspacings[r++];) {
- (function (cmd) {
- editorui['rowspacing' + cmd] = function (editor) {
- var val = editor.options['rowspacing' + cmd] || [];
- if(!val.length) return null;
- for (var i = 0, ci, items = []; ci = val[i++];) {
- items.push({
- label:ci,
- value:ci,
- theme:editor.options.theme,
- onclick:function () {
- editor.execCommand("rowspacing", this.value, cmd);
- }
- })
- }
- var ui = new editorui.MenuButton({
- editor:editor,
- className:'edui-for-rowspacing' + cmd,
- title:editor.options.labelMap['rowspacing' + cmd] || editor.getLang("labelMap.rowspacing" + cmd) || '',
- items:items,
- onbuttonclick:function () {
- var value = editor.queryCommandValue('rowspacing', cmd) || this.value;
- editor.execCommand("rowspacing", value, cmd);
- }
- });
- editorui.buttons[cmd]=ui;
- editor.addListener('selectionchange', function () {
- var state = editor.queryCommandState('rowspacing', cmd);
- if (state == -1) {
- ui.setDisabled(true);
- } else {
- ui.setDisabled(false);
- var value = editor.queryCommandValue('rowspacing', cmd);
- value && ui.setValue((value + '').replace(/%/, ''));
- ui.setChecked(state)
- }
- });
- return ui;
- }
- })(ri)
- }
- //有序,无序列表
- var lists = ['insertorderedlist', 'insertunorderedlist'];
- for (var l = 0, cl; cl = lists[l++];) {
- (function (cmd) {
- editorui[cmd] = function (editor) {
- var vals = editor.options[cmd],
- _onMenuClick = function () {
- editor.execCommand(cmd, this.value);
- }, items = [];
- for (var i in vals) {
- items.push({
- label:vals[i] || editor.getLang()[cmd][i] || "",
- value:i,
- theme:editor.options.theme,
- onclick:_onMenuClick
- })
- }
- var ui = new editorui.MenuButton({
- editor:editor,
- className:'edui-for-' + cmd,
- title:editor.getLang("labelMap." + cmd) || '',
- 'items':items,
- onbuttonclick:function () {
- var value = editor.queryCommandValue(cmd) || this.value;
- editor.execCommand(cmd, value);
- }
- });
- editorui.buttons[cmd]=ui;
- editor.addListener('selectionchange', function () {
- var state = editor.queryCommandState(cmd);
- if (state == -1) {
- ui.setDisabled(true);
- } else {
- ui.setDisabled(false);
- var value = editor.queryCommandValue(cmd);
- ui.setValue(value);
- ui.setChecked(state)
- }
- });
- return ui;
- };
- })(cl)
- }
- editorui.fullscreen = function (editor, title) {
- title = editor.options.labelMap['fullscreen'] || editor.getLang("labelMap.fullscreen") || '';
- var ui = new editorui.Button({
- className:'edui-for-fullscreen',
- title:title,
- theme:editor.options.theme,
- onclick:function () {
- if (editor.ui) {
- editor.ui.setFullScreen(!editor.ui.isFullScreen());
- }
- this.setChecked(editor.ui.isFullScreen());
- }
- });
- editorui.buttons['fullscreen']=ui;
- editor.addListener('selectionchange', function () {
- var state = editor.queryCommandState('fullscreen');
- ui.setDisabled(state == -1);
- ui.setChecked(editor.ui.isFullScreen());
- });
- return ui;
- };
- // 表情
- editorui.emotion = function (editor, iframeUrl) {
- var ui = new editorui.MultiMenuPop({
- title:editor.options.labelMap['emotion'] || editor.getLang("labelMap.emotion") || '',
- editor:editor,
- className:'edui-for-emotion',
- iframeUrl:editor.ui.mapUrl(iframeUrl || (editor.options.iframeUrlMap || {})['emotion'] || iframeUrlMap['emotion'])
- });
- editorui.buttons['emotion']=ui;
- editor.addListener('selectionchange', function () {
- ui.setDisabled(editor.queryCommandState('emotion') == -1)
- });
- return ui;
- };
- editorui.autotypeset = function (editor) {
- var ui = new editorui.AutoTypeSetButton({
- editor:editor,
- title:editor.options.labelMap['autotypeset'] || editor.getLang("labelMap.autotypeset") || '',
- className:'edui-for-autotypeset',
- onbuttonclick:function () {
- editor.execCommand('autotypeset')
- }
- });
- editorui.buttons['autotypeset']=ui;
- editor.addListener('selectionchange', function () {
- ui.setDisabled(editor.queryCommandState('autotypeset') == -1);
- });
- return ui;
- };
- })();
- ///import core
- ///commands 全屏
- ///commandsName FullScreen
- ///commandsTitle 全屏
- (function () {
- var utils = baidu.editor.utils,
- uiUtils = baidu.editor.ui.uiUtils,
- UIBase = baidu.editor.ui.UIBase,
- domUtils = baidu.editor.dom.domUtils;
- var nodeStack = [];
- function EditorUI(options) {
- this.initOptions(options);
- this.initEditorUI();
- }
- EditorUI.prototype = {
- uiName:'editor',
- initEditorUI:function () {
- this.editor.ui = this;
- this._dialogs = {};
- this.initUIBase();
- this._initToolbars();
- var editor = this.editor,
- me = this;
- editor.addListener('ready', function () {
- //提供getDialog方法
- editor.getDialog = function (name) {
- return editor.ui._dialogs[name + "Dialog"];
- };
- domUtils.on(editor.window, 'scroll', function (evt) {
- baidu.editor.ui.Popup.postHide(evt);
- });
- //提供编辑器实时宽高(全屏时宽高不变化)
- editor.ui._actualFrameWidth = editor.options.initialFrameWidth;
- //display bottom-bar label based on config
- if (editor.options.elementPathEnabled) {
- editor.ui.getDom('elementpath').innerHTML = '<div class="edui-editor-breadcrumb">' + editor.getLang("elementPathTip") + ':</div>';
- }
- if (editor.options.wordCount) {
- function countFn() {
- setCount(editor,me);
- domUtils.un(editor.document, "click", arguments.callee);
- }
- domUtils.on(editor.document, "click", countFn);
- editor.ui.getDom('wordcount').innerHTML = editor.getLang("wordCountTip");
- }
- editor.ui._scale();
- if (editor.options.scaleEnabled) {
- if (editor.autoHeightEnabled) {
- editor.disableAutoHeight();
- }
- me.enableScale();
- } else {
- me.disableScale();
- }
- if (!editor.options.elementPathEnabled && !editor.options.wordCount && !editor.options.scaleEnabled) {
- editor.ui.getDom('elementpath').style.display = "none";
- editor.ui.getDom('wordcount').style.display = "none";
- editor.ui.getDom('scale').style.display = "none";
- }
- if (!editor.selection.isFocus())return;
- editor.fireEvent('selectionchange', false, true);
- });
- editor.addListener('mousedown', function (t, evt) {
- var el = evt.target || evt.srcElement;
- baidu.editor.ui.Popup.postHide(evt, el);
- });
- editor.addListener("delcells", function () {
- if (UE.ui['edittip']) {
- new UE.ui['edittip'](editor);
- }
- editor.getDialog('edittip').open();
- });
- var pastePop, isPaste = false, timer;
- editor.addListener("afterpaste", function () {
- if(editor.queryCommandState('pasteplain'))
- return;
- pastePop = new baidu.editor.ui.Popup({
- content:new baidu.editor.ui.PastePicker({editor:editor}),
- editor:editor,
- className:'edui-wordpastepop'
- });
- pastePop.render();
- isPaste = true;
- });
- editor.addListener("afterinserthtml", function () {
- clearTimeout(timer);
- timer = setTimeout(function () {
- if (pastePop && (isPaste || editor.ui._isTransfer)) {
- var span = domUtils.createElement(editor.document, 'span', {
- 'style':"line-height:0px;",
- 'innerHTML':'\ufeff'
- }),
- range = editor.selection.getRange();
- range.insertNode(span);
- pastePop.showAnchor(span);
- domUtils.remove(span);
- delete editor.ui._isTransfer;
- isPaste = false;
- }
- }, 200)
- });
- editor.addListener('contextmenu', function (t, evt) {
- baidu.editor.ui.Popup.postHide(evt);
- });
- editor.addListener('keydown', function (t, evt) {
- if (pastePop) pastePop.dispose(evt);
- var keyCode = evt.keyCode || evt.which;
- if(evt.altKey&&keyCode==90){
- UE.ui.buttons['fullscreen'].onclick();
- }
- });
- editor.addListener('wordcount', function (type) {
- setCount(this,me);
- });
- function setCount(editor,ui) {
- editor.setOpt({
- wordCount:true,
- maximumWords:10000,
- wordCountMsg:editor.options.wordCountMsg || editor.getLang("wordCountMsg"),
- wordOverFlowMsg:editor.options.wordOverFlowMsg || editor.getLang("wordOverFlowMsg")
- });
- var opt = editor.options,
- max = opt.maximumWords,
- msg = opt.wordCountMsg ,
- errMsg = opt.wordOverFlowMsg,
- countDom = ui.getDom('wordcount');
- if (!opt.wordCount) {
- return;
- }
- var count = editor.getContentLength(true);
- if (count > max) {
- countDom.innerHTML = errMsg;
- editor.fireEvent("wordcountoverflow");
- } else {
- countDom.innerHTML = msg.replace("{#leave}", max - count).replace("{#count}", count);
- }
- }
- editor.addListener('selectionchange', function () {
- if (editor.options.elementPathEnabled) {
- me[(editor.queryCommandState('elementpath') == -1 ? 'dis' : 'en') + 'ableElementPath']()
- }
- if (editor.options.scaleEnabled) {
- me[(editor.queryCommandState('scale') == -1 ? 'dis' : 'en') + 'ableScale']();
- }
- });
- var popup = new baidu.editor.ui.Popup({
- editor:editor,
- content:'',
- className:'edui-bubble',
- _onEditButtonClick:function () {
- this.hide();
- editor.ui._dialogs.linkDialog.open();
- },
- _onImgEditButtonClick:function (name) {
- this.hide();
- editor.ui._dialogs[name] && editor.ui._dialogs[name].open();
- },
- _onImgSetFloat:function (value) {
- this.hide();
- editor.execCommand("imagefloat", value);
- },
- _setIframeAlign:function (value) {
- var frame = popup.anchorEl;
- var newFrame = frame.cloneNode(true);
- switch (value) {
- case -2:
- newFrame.setAttribute("align", "");
- break;
- case -1:
- newFrame.setAttribute("align", "left");
- break;
- case 1:
- newFrame.setAttribute("align", "right");
- break;
- }
- frame.parentNode.insertBefore(newFrame, frame);
- domUtils.remove(frame);
- popup.anchorEl = newFrame;
- popup.showAnchor(popup.anchorEl);
- },
- _updateIframe:function () {
- editor._iframe = popup.anchorEl;
- editor.ui._dialogs.insertframeDialog.open();
- popup.hide();
- },
- _onRemoveButtonClick:function (cmdName) {
- editor.execCommand(cmdName);
- this.hide();
- },
- queryAutoHide:function (el) {
- if (el && el.ownerDocument == editor.document) {
- if (el.tagName.toLowerCase() == 'img' || domUtils.findParentByTagName(el, 'a', true)) {
- return el !== popup.anchorEl;
- }
- }
- return baidu.editor.ui.Popup.prototype.queryAutoHide.call(this, el);
- }
- });
- popup.render();
- if (editor.options.imagePopup) {
- editor.addListener('mouseover', function (t, evt) {
- evt = evt || window.event;
- var el = evt.target || evt.srcElement;
- if (editor.ui._dialogs.insertframeDialog && /iframe/ig.test(el.tagName)) {
- var html = popup.formatHtml(
- '<nobr>' + editor.getLang("property") + ': <span onclick=$$._setIframeAlign(-2) class="edui-clickable">' + editor.getLang("default") + '</span> <span onclick=$$._setIframeAlign(-1) class="edui-clickable">' + editor.getLang("justifyleft") + '</span> <span onclick=$$._setIframeAlign(1) class="edui-clickable">' + editor.getLang("justifyright") + '</span> ' +
- ' <span onclick="$$._updateIframe( this);" class="edui-clickable">' + editor.getLang("modify") + '</span></nobr>');
- if (html) {
- popup.getDom('content').innerHTML = html;
- popup.anchorEl = el;
- popup.showAnchor(popup.anchorEl);
- } else {
- popup.hide();
- }
- }
- });
- editor.addListener('selectionchange', function (t, causeByUi) {
- if (!causeByUi) return;
- var html = '', str = "",
- img = editor.selection.getRange().getClosedNode(),
- dialogs = editor.ui._dialogs;
- if (img && img.tagName == 'IMG') {
- var dialogName = 'insertimageDialog';
- if (img.className.indexOf("edui-faked-video") != -1) {
- dialogName = "insertvideoDialog"
- }
- if (img.className.indexOf("edui-faked-webapp") != -1) {
- dialogName = "webappDialog"
- }
- if (img.src.indexOf("http://api.map.baidu.com") != -1) {
- dialogName = "mapDialog"
- }
- if (img.className.indexOf("edui-faked-music") != -1) {
- dialogName = "musicDialog"
- }
- if (img.src.indexOf("http://maps.google.com/maps/api/staticmap") != -1) {
- dialogName = "gmapDialog"
- }
- if (img.getAttribute("anchorname")) {
- dialogName = "anchorDialog";
- html = popup.formatHtml(
- '<nobr>' + editor.getLang("property") + ': <span onclick=$$._onImgEditButtonClick("anchorDialog") class="edui-clickable">' + editor.getLang("modify") + '</span> ' +
- '<span onclick=$$._onRemoveButtonClick(\'anchor\') class="edui-clickable">' + editor.getLang("delete") + '</span></nobr>');
- }
- if (img.getAttribute("word_img")) {
- //todo 放到dialog去做查询
- editor.word_img = [img.getAttribute("word_img")];
- dialogName = "wordimageDialog"
- }
- if (!dialogs[dialogName]) {
- return;
- }
- str = '<nobr>' + editor.getLang("property") + ': '+
- '<span onclick=$$._onImgSetFloat("none") class="edui-clickable">' + editor.getLang("default") + '</span> ' +
- '<span onclick=$$._onImgSetFloat("left") class="edui-clickable">' + editor.getLang("justifyleft") + '</span> ' +
- '<span onclick=$$._onImgSetFloat("right") class="edui-clickable">' + editor.getLang("justifyright") + '</span> ' +
- '<span onclick=$$._onImgSetFloat("center") class="edui-clickable">' + editor.getLang("justifycenter") + '</span> '+
- '<span onclick="$$._onImgEditButtonClick(\'' + dialogName + '\');" class="edui-clickable">' + editor.getLang("modify") + '</span></nobr>';
- !html && (html = popup.formatHtml(str))
- }
- if (editor.ui._dialogs.linkDialog) {
- var link = editor.queryCommandValue('link');
- var url;
- if (link && (url = (link.getAttribute('data_ue_src') || link.getAttribute('href', 2)))) {
- var txt = url;
- if (url.length > 30) {
- txt = url.substring(0, 20) + "...";
- }
- if (html) {
- html += '<div style="height:5px;"></div>'
- }
- html += popup.formatHtml(
- '<nobr>' + editor.getLang("anthorMsg") + ': <a target="_blank" href="' + url + '" title="' + url + '" >' + txt + '</a>' +
- ' <span class="edui-clickable" onclick="$$._onEditButtonClick();">' + editor.getLang("modify") + '</span>' +
- ' <span class="edui-clickable" onclick="$$._onRemoveButtonClick(\'unlink\');"> ' + editor.getLang("clear") + '</span></nobr>');
- popup.showAnchor(link);
- }
- }
- if (html) {
- popup.getDom('content').innerHTML = html;
- popup.anchorEl = img || link;
- popup.showAnchor(popup.anchorEl);
- } else {
- popup.hide();
- }
- });
- }
- },
- _initToolbars:function () {
- var editor = this.editor;
- var toolbars = this.toolbars || [];
- var toolbarUis = [];
- for (var i = 0; i < toolbars.length; i++) {
- var toolbar = toolbars[i];
- var toolbarUi = new baidu.editor.ui.Toolbar({theme:editor.options.theme});
- for (var j = 0; j < toolbar.length; j++) {
- var toolbarItem = toolbar[j];
- var toolbarItemUi = null;
- if (typeof toolbarItem == 'string') {
- toolbarItem = toolbarItem.toLowerCase();
- if (toolbarItem == '|') {
- toolbarItem = 'Separator';
- }
- if (baidu.editor.ui[toolbarItem]) {
- toolbarItemUi = new baidu.editor.ui[toolbarItem](editor);
- }
- //fullscreen这里单独处理一下,放到首行去
- if (toolbarItem == 'fullscreen') {
- if (toolbarUis && toolbarUis[0]) {
- toolbarUis[0].items.splice(0, 0, toolbarItemUi);
- } else {
- toolbarItemUi && toolbarUi.items.splice(0, 0, toolbarItemUi);
- }
- continue;
- }
- } else {
- toolbarItemUi = toolbarItem;
- }
- if (toolbarItemUi && toolbarItemUi.id) {
- toolbarUi.add(toolbarItemUi);
- }
- }
- toolbarUis[i] = toolbarUi;
- }
- this.toolbars = toolbarUis;
- },
- getHtmlTpl:function () {
- return '<div id="##" class="%%">' +
- '<div id="##_toolbarbox" class="%%-toolbarbox">' +
- (this.toolbars.length ?
- '<div id="##_toolbarboxouter" class="%%-toolbarboxouter"><div class="%%-toolbarboxinner">' +
- this.renderToolbarBoxHtml() +
- '</div></div>' : '') +
- '<div id="##_toolbarmsg" class="%%-toolbarmsg" style="display:none;">' +
- '<div id = "##_upload_dialog" class="%%-toolbarmsg-upload" onclick="$$.showWordImageDialog();">' + this.editor.getLang("clickToUpload") + '</div>' +
- '<div class="%%-toolbarmsg-close" onclick="$$.hideToolbarMsg();">x</div>' +
- '<div id="##_toolbarmsg_label" class="%%-toolbarmsg-label"></div>' +
- '<div style="height:0;overflow:hidden;clear:both;"></div>' +
- '</div>' +
- '</div>' +
- '<div id="##_iframeholder" class="%%-iframeholder"></div>' +
- //modify wdcount by matao
- '<div id="##_bottombar" class="%%-bottomContainer"><table><tr>' +
- '<td id="##_elementpath" class="%%-bottombar"></td>' +
- '<td id="##_wordcount" class="%%-wordcount"></td>' +
- '<td id="##_scale" class="%%-scale"><div class="%%-icon"></div></td>' +
- '</tr></table></div>' +
- '<div id="##_scalelayer"></div>' +
- '</div>';
- },
- showWordImageDialog:function () {
- this.editor.execCommand("wordimage", "word_img");
- this._dialogs['wordimageDialog'].open();
- },
- renderToolbarBoxHtml:function () {
- var buff = [];
- for (var i = 0; i < this.toolbars.length; i++) {
- buff.push(this.toolbars[i].renderHtml());
- }
- return buff.join('');
- },
- setFullScreen:function (fullscreen) {
- var editor = this.editor,
- container = editor.container.parentNode.parentNode;
- if (this._fullscreen != fullscreen) {
- this._fullscreen = fullscreen;
- this.editor.fireEvent('beforefullscreenchange', fullscreen);
- if (baidu.editor.browser.gecko) {
- var bk = editor.selection.getRange().createBookmark();
- }
- if (fullscreen) {
- while (container.tagName != "BODY") {
- var position = baidu.editor.dom.domUtils.getComputedStyle(container, "position");
- nodeStack.push(position);
- container.style.position = "static";
- container = container.parentNode;
- }
- this._bakHtmlOverflow = document.documentElement.style.overflow;
- this._bakBodyOverflow = document.body.style.overflow;
- this._bakAutoHeight = this.editor.autoHeightEnabled;
- this._bakScrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
- if (this._bakAutoHeight) {
- //当全屏时不能执行自动长高
- editor.autoHeightEnabled = false;
- this.editor.disableAutoHeight();
- }
- document.documentElement.style.overflow = 'hidden';
- document.body.style.overflow = 'hidden';
- this._bakCssText = this.getDom().style.cssText;
- this._bakCssText1 = this.getDom('iframeholder').style.cssText;
- this._updateFullScreen();
- } else {
- while (container.tagName != "BODY") {
- container.style.position = nodeStack.shift();
- container = container.parentNode;
- }
- this.getDom().style.cssText = this._bakCssText;
- this.getDom('iframeholder').style.cssText = this._bakCssText1;
- if (this._bakAutoHeight) {
- editor.autoHeightEnabled = true;
- this.editor.enableAutoHeight();
- }
- document.documentElement.style.overflow = this._bakHtmlOverflow;
- document.body.style.overflow = this._bakBodyOverflow;
- window.scrollTo(0, this._bakScrollTop);
- }
- if (baidu.editor.browser.gecko) {
- var input = document.createElement('input');
- document.body.appendChild(input);
- editor.body.contentEditable = false;
- setTimeout(function () {
- input.focus();
- setTimeout(function () {
- editor.body.contentEditable = true;
- editor.selection.getRange().moveToBookmark(bk).select(true);
- baidu.editor.dom.domUtils.remove(input);
- fullscreen && window.scroll(0, 0);
- }, 0)
- }, 0)
- }
- this.editor.fireEvent('fullscreenchanged', fullscreen);
- this.triggerLayout();
- }
- },
- _updateFullScreen:function () {
- if (this._fullscreen) {
- var vpRect = uiUtils.getViewportRect();
- this.getDom().style.cssText = 'border:0;position:absolute;left:0;top:' + (this.editor.options.topOffset || 0) + 'px;width:' + vpRect.width + 'px;height:' + vpRect.height + 'px;z-index:' + (this.getDom().style.zIndex * 1 + 100);
- uiUtils.setViewportOffset(this.getDom(), { left:0, top:this.editor.options.topOffset || 0 });
- this.editor.setHeight(vpRect.height - this.getDom('toolbarbox').offsetHeight - this.getDom('bottombar').offsetHeight - (this.editor.options.topOffset || 0));
- }
- },
- _updateElementPath:function () {
- var bottom = this.getDom('elementpath'), list;
- if (this.elementPathEnabled && (list = this.editor.queryCommandValue('elementpath'))) {
- var buff = [];
- for (var i = 0, ci; ci = list[i]; i++) {
- buff[i] = this.formatHtml('<span unselectable="on" onclick="$$.editor.execCommand("elementpath", "' + i + '");">' + ci + '</span>');
- }
- bottom.innerHTML = '<div class="edui-editor-breadcrumb" onmousedown="return false;">' + this.editor.getLang("elementPathTip") + ': ' + buff.join(' > ') + '</div>';
- } else {
- bottom.style.display = 'none'
- }
- },
- disableElementPath:function () {
- var bottom = this.getDom('elementpath');
- bottom.innerHTML = '';
- bottom.style.display = 'none';
- this.elementPathEnabled = false;
- },
- enableElementPath:function () {
- var bottom = this.getDom('elementpath');
- bottom.style.display = '';
- this.elementPathEnabled = true;
- this._updateElementPath();
- },
- _scale:function () {
- var doc = document,
- editor = this.editor,
- editorHolder = editor.container,
- editorDocument = editor.document,
- toolbarBox = this.getDom("toolbarbox"),
- bottombar = this.getDom("bottombar"),
- scale = this.getDom("scale"),
- scalelayer = this.getDom("scalelayer");
- var isMouseMove = false,
- position = null,
- minEditorHeight = 0,
- minEditorWidth = editor.options.minFrameWidth,
- pageX = 0,
- pageY = 0,
- scaleWidth = 0,
- scaleHeight = 0;
- function down() {
- position = domUtils.getXY(editorHolder);
- if (!minEditorHeight) {
- minEditorHeight = editor.options.minFrameHeight + toolbarBox.offsetHeight + bottombar.offsetHeight;
- }
- scalelayer.style.cssText = "position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:" + editorHolder.offsetWidth + "px;height:"
- + editorHolder.offsetHeight + "px;z-index:" + (editor.options.zIndex + 1);
- domUtils.on(doc, "mousemove", move);
- domUtils.on(editorDocument, "mouseup", up);
- domUtils.on(doc, "mouseup", up);
- }
- var me = this;
- //by xuheng 全屏时关掉缩放
- this.editor.addListener('fullscreenchanged', function (e, fullScreen) {
- if (fullScreen) {
- me.disableScale();
- } else {
- if (me.editor.options.scaleEnabled) {
- me.enableScale();
- var tmpNode = me.editor.document.createElement('span');
- me.editor.body.appendChild(tmpNode);
- me.editor.body.style.height = Math.max(domUtils.getXY(tmpNode).y, me.editor.iframe.offsetHeight - 20) + 'px';
- domUtils.remove(tmpNode)
- }
- }
- });
- function move(event) {
- clearSelection();
- var e = event || window.event;
- pageX = e.pageX || (doc.documentElement.scrollLeft + e.clientX);
- pageY = e.pageY || (doc.documentElement.scrollTop + e.clientY);
- scaleWidth = pageX - position.x;
- scaleHeight = pageY - position.y;
- if (scaleWidth >= minEditorWidth) {
- isMouseMove = true;
- scalelayer.style.width = scaleWidth + 'px';
- }
- if (scaleHeight >= minEditorHeight) {
- isMouseMove = true;
- scalelayer.style.height = scaleHeight + "px";
- }
- }
- function up() {
- if (isMouseMove) {
- isMouseMove = false;
- editor.ui._actualFrameWidth = scalelayer.offsetWidth - 2;
- editorHolder.style.width = editor.ui._actualFrameWidth + 'px';
- editor.setHeight(scalelayer.offsetHeight - bottombar.offsetHeight - toolbarBox.offsetHeight - 2);
- }
- if (scalelayer) {
- scalelayer.style.display = "none";
- }
- clearSelection();
- domUtils.un(doc, "mousemove", move);
- domUtils.un(editorDocument, "mouseup", up);
- domUtils.un(doc, "mouseup", up);
- }
- function clearSelection() {
- if (browser.ie)
- doc.selection.clear();
- else
- window.getSelection().removeAllRanges();
- }
- this.enableScale = function () {
- //trace:2868
- if (editor.queryCommandState("source") == 1) return;
- scale.style.display = "";
- this.scaleEnabled = true;
- domUtils.on(scale, "mousedown", down);
- };
- this.disableScale = function () {
- scale.style.display = "none";
- this.scaleEnabled = false;
- domUtils.un(scale, "mousedown", down);
- };
- },
- isFullScreen:function () {
- return this._fullscreen;
- },
- postRender:function () {
- UIBase.prototype.postRender.call(this);
- for (var i = 0; i < this.toolbars.length; i++) {
- this.toolbars[i].postRender();
- }
- var me = this;
- var timerId,
- domUtils = baidu.editor.dom.domUtils,
- updateFullScreenTime = function () {
- clearTimeout(timerId);
- timerId = setTimeout(function () {
- me._updateFullScreen();
- });
- };
- domUtils.on(window, 'resize', updateFullScreenTime);
- me.addListener('destroy', function () {
- domUtils.un(window, 'resize', updateFullScreenTime);
- clearTimeout(timerId);
- })
- },
- showToolbarMsg:function (msg, flag) {
- this.getDom('toolbarmsg_label').innerHTML = msg;
- this.getDom('toolbarmsg').style.display = '';
- //
- if (!flag) {
- var w = this.getDom('upload_dialog');
- w.style.display = 'none';
- }
- },
- hideToolbarMsg:function () {
- this.getDom('toolbarmsg').style.display = 'none';
- },
- mapUrl:function (url) {
- return url ? url.replace('~/', this.editor.options.UEDITOR_HOME_URL || '') : ''
- },
- triggerLayout:function () {
- var dom = this.getDom();
- if (dom.style.zoom == '1') {
- dom.style.zoom = '100%';
- } else {
- dom.style.zoom = '1';
- }
- }
- };
- utils.inherits(EditorUI, baidu.editor.ui.UIBase);
- var instances = {};
- UE.ui.Editor = function (options) {
- var editor = new baidu.editor.Editor(options);
- editor.options.editor = editor;
- utils.loadFile(document, {
- href:editor.options.themePath + editor.options.theme + "/css/ueditor.css",
- tag:"link",
- type:"text/css",
- rel:"stylesheet"
- });
- var oldRender = editor.render;
- editor.render = function (holder) {
- if (holder.constructor === String) {
- editor.key = holder;
- instances[holder] = editor;
- }
- utils.domReady(function () {
- editor.langIsReady ? renderUI() : editor.addListener("langReady", renderUI);
- function renderUI() {
- editor.setOpt({
- labelMap:editor.options.labelMap || editor.getLang('labelMap')
- });
- new EditorUI(editor.options);
- if (holder) {
- if (holder.constructor === String) {
- holder = document.getElementById(holder);
- }
- holder && holder.getAttribute('name') && ( editor.options.textarea = holder.getAttribute('name'));
- if (holder && /script|textarea/ig.test(holder.tagName)) {
- var newDiv = document.createElement('div');
- holder.parentNode.insertBefore(newDiv, holder);
- var cont = holder.value || holder.innerHTML;
- editor.options.initialContent = /^[\t\r\n ]*$/.test(cont) ? editor.options.initialContent :
- cont.replace(/>[\n\r\t]+([ ]{4})+/g, '>')
- .replace(/[\n\r\t]+([ ]{4})+</g, '<')
- .replace(/>[\n\r\t]+</g, '><');
- holder.className && (newDiv.className = holder.className);
- holder.style.cssText && (newDiv.style.cssText = holder.style.cssText);
- if (/textarea/i.test(holder.tagName)) {
- editor.textarea = holder;
- editor.textarea.style.display = 'none';
- } else {
- holder.parentNode.removeChild(holder);
- holder.id && (newDiv.id = holder.id);
- }
- holder = newDiv;
- holder.innerHTML = '';
- }
- }
- domUtils.addClass(holder, "edui-" + editor.options.theme);
- editor.ui.render(holder);
- var iframeholder = editor.ui.getDom('iframeholder');
- //给实例添加一个编辑器的容器引用
- editor.container = editor.ui.getDom();
- var width = editor.options.initialFrameWidth;
- if (!/%/g.test(width)) width += "px";
- editor.container.style.cssText = "z-index:" + editor.options.zIndex + ";width:" + width;
- oldRender.call(editor, iframeholder);
- }
- })
- };
- return editor;
- };
- /**
- * @file
- * @name UE
- * @short UE
- * @desc UEditor的顶部命名空间
- */
- /**
- * @name getEditor
- * @since 1.2.4+
- * @grammar UE.getEditor(id,[opt]) => Editor实例
- * @desc 提供一个全局的方法得到编辑器实例
- *
- * * ''id'' 放置编辑器的容器id, 如果容器下的编辑器已经存在,就直接返回
- * * ''opt'' 编辑器的可选参数
- * @example
- * UE.getEditor('containerId',{onready:function(){//创建一个编辑器实例
- * this.setContent('hello')
- * }});
- * UE.getEditor('containerId'); //返回刚创建的实例
- *
- */
- UE.getEditor = function (id, opt) {
- var editor = instances[id];
- if (!editor) {
- editor = instances[id] = new UE.ui.Editor(opt);
- editor.render(id);
- }
- return editor;
- };
- UE.delEditor = function (id) {
- var editor;
- if (editor = instances[id]) {
- editor.key && editor.destroy();
- delete instances[id]
- }
- }
- })();
- ///import core
- ///import uicore
- ///commands 表情
- (function(){
- var utils = baidu.editor.utils,
- Popup = baidu.editor.ui.Popup,
- SplitButton = baidu.editor.ui.SplitButton,
- MultiMenuPop = baidu.editor.ui.MultiMenuPop = function(options){
- this.initOptions(options);
- this.initMultiMenu();
- };
- MultiMenuPop.prototype = {
- initMultiMenu: function (){
- var me = this;
- this.popup = new Popup({
- content: '',
- editor : me.editor,
- iframe_rendered: false,
- onshow: function (){
- if (!this.iframe_rendered) {
- this.iframe_rendered = true;
- this.getDom('content').innerHTML = '<iframe id="'+me.id+'_iframe" src="'+ me.iframeUrl +'" frameborder="0"></iframe>';
- me.editor.container.style.zIndex && (this.getDom().style.zIndex = me.editor.container.style.zIndex * 1 + 1);
- }
- }
- // canSideUp:false,
- // canSideLeft:false
- });
- this.onbuttonclick = function(){
- this.showPopup();
- };
- this.initSplitButton();
- }
- };
- utils.inherits(MultiMenuPop, SplitButton);
- })();
- })();
|