Opera 12.15 Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

docman.cpp 262KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355
  1. /* -*- Mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; c-file-style:"stroustrup" -*-
  2. *
  3. * Copyright (C) 1995-2011 Opera Software ASA. All rights reserved.
  4. *
  5. * This file is part of the Opera web browser.
  6. * It may not be distributed under any circumstances.
  7. */
  8. #include "core/pch.h"
  9. #include "modules/dochand/docman.h"
  10. #ifdef CLIENTSIDE_STORAGE_SUPPORT
  11. # include "modules/database/opstorage.h"
  12. #endif //CLIENTSIDE_STORAGE_SUPPORT
  13. #include "modules/display/vis_dev.h"
  14. #include "modules/display/prn_dev.h"
  15. #include "modules/display/coreview/coreview.h"
  16. #include "modules/doc/frm_doc.h"
  17. #include "modules/doc/html_doc.h"
  18. #include "modules/dochand/fdelm.h"
  19. #include "modules/dochand/fraud_check.h"
  20. #include "modules/dochand/viewportcontroller.h"
  21. #include "modules/dochand/win.h"
  22. #include "modules/dochand/winman.h"
  23. #include "modules/probetools/probepoints.h"
  24. #include "modules/ecmascript/ecmascript.h"
  25. #include "modules/hardcore/base/opstatus.h"
  26. #include "modules/hardcore/mh/messages.h"
  27. #include "modules/img/image.h"
  28. #include "modules/locale/oplanguagemanager.h"
  29. #include "modules/pi/OpWindow.h"
  30. #include "modules/display/prn_info.h"
  31. #include "modules/viewers/viewers.h"
  32. #include "modules/url/url2.h"
  33. #include "modules/url/url_sn.h"
  34. #include "modules/url/url_man.h"
  35. #include "modules/url/url_tools.h"
  36. #include "modules/url/url_lop_api.h" // OperaURL_Generator
  37. #include "modules/util/handy.h"
  38. #include "modules/util/filefun.h"
  39. #include "modules/util/htmlify.h"
  40. #include "modules/util/winutils.h"
  41. #include "modules/logdoc/urlimgcontprov.h"
  42. #include "modules/logdoc/selection.h"
  43. #include "modules/layout/layout_workplace.h"
  44. #include "modules/layout/traverse/traverse.h"
  45. #include "modules/formats/uri_escape.h"
  46. #include "modules/prefs/prefsmanager/collections/pc_app.h"
  47. #include "modules/prefs/prefsmanager/collections/pc_display.h"
  48. #include "modules/prefs/prefsmanager/collections/pc_doc.h"
  49. #include "modules/prefs/prefsmanager/collections/pc_fontcolor.h"
  50. #include "modules/prefs/prefsmanager/collections/pc_js.h"
  51. #include "modules/prefs/prefsmanager/collections/pc_network.h"
  52. #include "modules/prefs/prefsmanager/collections/pc_print.h"
  53. #include "modules/about/operafraudwarning.h"
  54. #ifdef ERROR_PAGE_SUPPORT
  55. #include "modules/about/opcrossnetworkerror.h"
  56. #endif // ERROR_PAGE_SUPPORT
  57. #include "modules/about/opsuppressedurl.h"
  58. #include "modules/about/opclickjackingblock.h"
  59. #ifdef WEBFEEDS_DISPLAY_SUPPORT
  60. # include "modules/webfeeds/webfeeds_api.h"
  61. #endif // WEBFEEDS_DISPLAY_SUPPORT
  62. #ifdef PREFS_DOWNLOAD
  63. # include "modules/prefsloader/prefsloadmanager.h"
  64. #endif // PREFS_DOWNLOAD
  65. #if defined OPERA_CONSOLE && defined ERROR_PAGE_SUPPORT
  66. # include "modules/console/opconsoleengine.h"
  67. #endif // OPERA_CONSOLE && ERROR_PAGE_SUPPORT
  68. #ifdef QUICK
  69. # include "adjunct/quick/hotlist/HotlistManager.h"
  70. # include "adjunct/quick/Application.h"
  71. #endif
  72. #ifdef OPERA_SETUP_DOWNLOAD_APPLY_SUPPORT
  73. # ifdef _KIOSK_MANAGER_
  74. # include "adjunct/quick/managers/KioskManager.h"
  75. # endif // _KIOSK_MANAGER_
  76. #endif //OPERA_SETUP_DOWNLOAD_APPLY_SUPPORT
  77. #ifdef EXTERNAL_PROTOCOL_HANDLER_SUPPORT
  78. # include "modules/url/loadhandler/url_eph.h"
  79. #endif // EXTERNAL_PROTOCOL_HANDLER_SUPPORT
  80. #ifdef _PLUGIN_SUPPORT_
  81. # include "modules/ns4plugins/opns4pluginhandler.h"
  82. #endif // _PLUGIN_SUPPORT_
  83. #include "modules/ecmascript/ecmascript.h"
  84. #include "modules/ecmascript_utils/essched.h"
  85. #include "modules/ecmascript_utils/esthread.h"
  86. #include "modules/ecmascript_utils/esterm.h"
  87. #include "modules/dom/domenvironment.h"
  88. #ifdef _SPAT_NAV_SUPPORT_
  89. # include "modules/spatial_navigation/handler_api.h"
  90. #endif // _SPAT_NAV_SUPPORT_
  91. #ifdef _WML_SUPPORT_
  92. # include "modules/logdoc/wml.h"
  93. #endif // _WML_SUPPORT_
  94. #include "modules/windowcommander/src/WindowCommander.h"
  95. #ifdef WIC_USE_DOWNLOAD_CALLBACK
  96. # include "modules/windowcommander/src/TransferManagerDownload.h"
  97. #endif // WIC_USE_DOWNLOAD_CALLBACK
  98. #ifdef XML_AIT_SUPPORT
  99. # include "modules/windowcommander/AITData.h"
  100. # include "modules/dochand/aitparser.h"
  101. #endif // XML_AIT_SUPPORT
  102. #ifdef _BITTORRENT_SUPPORT_
  103. # include "adjunct/bittorrent/bt-info.h"
  104. #endif // _BITTORRENT_SUPPORT_
  105. #ifdef M2_SUPPORT
  106. # include "adjunct/m2/src/engine/engine.h"
  107. #endif // M2_SUPPORT
  108. #ifdef WEBSERVER_SUPPORT
  109. #include "modules/about/operauniteadminwarning.h"
  110. #endif // WEBSERVER_SUPPORT
  111. #if defined _SSL_SUPPORT_ && !defined _EXTERNAL_SSL_SUPPORT_ && !defined _CERTICOM_SSL_SUPPORT_
  112. # include "modules/libssl/sslv3.h"
  113. # include "modules/libssl/sslopt.h"
  114. # include "modules/libssl/ssl_api.h"
  115. # include "modules/libssl/certinst_base.h"
  116. # include "modules/windowcommander/src/SSLSecurtityPasswordCallbackImpl.h"
  117. #endif // _SSL_SUPPORT_ && !_EXTERNAL_SSL_SUPPORT_ && !_CERTICOM_SSL_SUPPORT_
  118. #define DOCHAND_THREAD_MIGRATION
  119. #ifdef GADGET_SUPPORT
  120. # include "modules/gadgets/OpGadget.h"
  121. #endif // GADGET_SUPPORT
  122. #ifdef SVG_SUPPORT
  123. # include "modules/svg/SVGManager.h"
  124. # include "modules/svg/svg_image.h"
  125. #endif // SVG_SUPPORT
  126. #ifdef APPLICATION_CACHE_SUPPORT
  127. # include "modules/applicationcache/application_cache_manager.h"
  128. #endif // APPLICATION_CACHE_SUPPORT
  129. #ifdef SCOPE_DOCUMENT_MANAGER
  130. # include "modules/scope/scope_document_listener.h"
  131. #endif // SCOPE_DOCUMENT_MANAGER
  132. #ifdef SCOPE_PROFILER
  133. # include "modules/probetools/probetimeline.h"
  134. #endif // SCOPE_PROFILER
  135. #ifdef WEB_HANDLERS_SUPPORT
  136. # include "modules/forms/tempbuffer8.h"
  137. #endif // WEB_HANDLERS_SUPPORT
  138. #ifdef HC_CAP_ERRENUM_AS_STRINGENUM
  139. #define DH_ERRSTR(p,x) Str::##p##_##x
  140. #else
  141. #define DH_ERRSTR(p,x) x
  142. #endif
  143. class QueuedMessageElm
  144. : public Link
  145. {
  146. public:
  147. OpMessage msg;
  148. URL_ID url_id;
  149. MH_PARAM_2 user_data;
  150. IAmLoadingThisURL target_url; // To prevent the target URL from being reloaded while queued.
  151. };
  152. BOOL DocListElm::MaybeReassignDocOwnership()
  153. {
  154. if (owns_doc)
  155. {
  156. /* The element that owns the document is always first in list, so we
  157. only need to search the following part of the list for elements that
  158. share document with us. */
  159. DocListElm* dle = Suc();
  160. while (dle)
  161. {
  162. if (dle->doc == doc)
  163. {
  164. doc = NULL;
  165. owns_doc = FALSE;
  166. dle->owns_doc = TRUE;
  167. return TRUE;
  168. }
  169. dle = dle->Suc();
  170. }
  171. }
  172. return FALSE;
  173. }
  174. int
  175. DocumentManager::GetNextDocListElmId()
  176. {
  177. if (!GetParentDoc())
  178. {
  179. return GetWindow()->GetNextDocListElmId();
  180. }
  181. else
  182. {
  183. return HistoryIdNotSet;
  184. }
  185. }
  186. DocListElm::DocListElm(const URL& doc_url, FramesDocument* d, BOOL own, int n, UINT32 id)
  187. : m_id(id)
  188. {
  189. url = doc_url;
  190. referrer_url = DocumentReferrer();
  191. send_to_server = TRUE;
  192. doc = d;
  193. owns_doc = own;
  194. replaceable = FALSE;
  195. precreated = FALSE;
  196. has_visual_viewport = FALSE;
  197. #ifdef PAGED_MEDIA_SUPPORT
  198. current_page = -1;
  199. #endif
  200. number = n;
  201. last_layout_mode = doc ? doc->GetLayoutMode() : LAYOUT_NORMAL;
  202. last_scale = doc ? doc->GetWindow()->GetScale() : 100;
  203. script_generated_doc = FALSE;
  204. replaced_empty_position = FALSE;
  205. #ifdef _WML_SUPPORT_
  206. wml_context = NULL;
  207. #endif // _WML_SUPPORT_
  208. m_data = NULL;
  209. m_user_data = NULL;
  210. }
  211. DocListElm::~DocListElm()
  212. {
  213. if (owns_doc)
  214. OP_DELETE(doc);
  215. #ifdef _WML_SUPPORT_
  216. if (wml_context)
  217. {
  218. wml_context->DecRef();
  219. wml_context = NULL;
  220. }
  221. #endif // _WML_SUPPORT_
  222. OP_DELETE(m_data);
  223. OP_DELETE(m_user_data);
  224. }
  225. OP_STATUS DocListElm::SetTitle(const uni_char* val)
  226. {
  227. if (title.Compare(val) != 0)
  228. return title.Set(val);
  229. return OpStatus::OK;
  230. }
  231. void DocListElm::SetUserData(OpHistoryUserData* user_data)
  232. {
  233. OP_DELETE(m_user_data);
  234. m_user_data = user_data;
  235. }
  236. OpHistoryUserData* DocListElm::GetUserData() const
  237. {
  238. return m_user_data;
  239. }
  240. void DocListElm::Out()
  241. {
  242. MaybeReassignDocOwnership();
  243. Link::Out();
  244. }
  245. void DocListElm::ReplaceDoc(FramesDocument* d)
  246. {
  247. if (owns_doc)
  248. {
  249. MaybeReassignDocOwnership();
  250. OP_DELETE(doc);
  251. }
  252. doc = d;
  253. }
  254. BOOL DocListElm::HasPreceding()
  255. {
  256. DocListElm *preceding = Pred();
  257. while (preceding)
  258. if (preceding->number != number)
  259. return TRUE;
  260. else
  261. preceding = preceding->Pred();
  262. return FALSE;
  263. }
  264. #ifdef _WML_SUPPORT_
  265. void
  266. DocListElm::SetWmlContext(WML_Context *new_ctx)
  267. {
  268. if (wml_context != new_ctx)
  269. {
  270. if (wml_context)
  271. wml_context->DecRef();
  272. wml_context = new_ctx;
  273. if (wml_context)
  274. wml_context->IncRef();
  275. }
  276. }
  277. #endif // _WML_SUPPORT_
  278. void
  279. DocListElm::SetData(ES_PersistentValue *data)
  280. {
  281. OP_DELETE(m_data);
  282. m_data = data;
  283. }
  284. BOOL IsAboutBlankURL(const URL& url)
  285. {
  286. if (url.Type() == URL_OPERA)
  287. {
  288. OpStringC8 name(url.GetAttribute(URL::KName));
  289. if (name.CompareI("about:blank") == 0)
  290. return TRUE;
  291. #ifdef SELFTEST
  292. if (name.CompareI("opera:blanker") == 0)
  293. return TRUE;
  294. #endif // SELFTEST
  295. }
  296. return FALSE;
  297. }
  298. BOOL IsURLSuitableSecurityContext(URL url)
  299. {
  300. if (url.GetAttribute(URL::KUniHostName).HasContent())
  301. return TRUE;
  302. if (url.Type() == URL_OPERA && !IsAboutBlankURL(url))
  303. return TRUE;
  304. return FALSE;
  305. }
  306. void
  307. DocumentManager::NotifyUrlChangedIfAppropriate(URL& url)
  308. {
  309. // Did this to get the URL in the URL-field early for empty windows
  310. if (!current_doc_elm && doc_list.Empty() && !parent_doc)
  311. {
  312. uni_char *tempname = Window::ComposeLinkInformation(url.GetAttribute(URL::KUniName_Username_Password_Hidden).CStr(), url.GetAttribute(URL::KUniFragment_Name).CStr());
  313. WindowCommander *win_com = window->GetWindowCommander();
  314. win_com->GetLoadingListener()->OnUrlChanged(win_com, tempname);
  315. OP_DELETEA(tempname);
  316. }
  317. }
  318. void
  319. DocumentManager::HandleCallback(OpMessage msg, MH_PARAM_1 par1, MH_PARAM_2 par2)
  320. {
  321. BOOL oom = FALSE;
  322. FramesDocument* frames_doc = NULL;
  323. #ifdef _PRINT_SUPPORT_
  324. if (window->GetPreviewMode() || window->GetPrintMode())
  325. frames_doc = GetPrintDoc();
  326. else
  327. #endif
  328. frames_doc = GetCurrentDoc();
  329. #ifdef LOCALE_CONTEXTS
  330. if (frames_doc)
  331. g_languageManager->SetContext(frames_doc->GetURL().GetContextId());
  332. #endif
  333. switch (msg)
  334. {
  335. #ifdef COOKIE_WARNING_SUPPORT
  336. case MSG_COOKIE_SET:
  337. {
  338. WindowCommander *wc = window->GetWindowCommander();
  339. wc->GetDocumentListener()->OnCookieWriteDenied(wc);
  340. break;
  341. }
  342. #endif // COOKIE_WARNING_SUPPORT
  343. case MSG_HANDLE_BY_OPERA:
  344. // par1: ignored
  345. // par2: arguments to HandleByOpera (check_if_inline_expired | use_plugin << 1 | user_requested << 2)
  346. g_windowManager->UpdateVisitedLinks(GetCurrentURL(), HandleByOpera((par2 & 1) != 0, (par2 & 2) != 0, (par2 & 4) != 0, &oom) ? window : NULL);
  347. break;
  348. case MSG_REFLOW_DOCUMENT:
  349. // par1: ignored
  350. // par2: arguments to ClearReflowMsgFlag and Reflow (frameset)
  351. if (frames_doc)
  352. {
  353. frames_doc->ClearReflowMsgFlag(!!par2);
  354. LayoutWorkplace* wp = frames_doc->GetLogicalDocument() ? frames_doc->GetLogicalDocument()->GetLayoutWorkplace() : NULL;
  355. if (wp)
  356. wp->SetCanYield(TRUE);
  357. OP_STATUS status = frames_doc->Reflow(FALSE, FALSE, !!par2);
  358. if (status == OpStatus::ERR_YIELD)
  359. mh->PostMessage(MSG_REFLOW_DOCUMENT, 0, 0);
  360. else
  361. RaiseCondition(status);
  362. if (wp)
  363. wp->SetCanYield(FALSE);
  364. }
  365. break;
  366. case MSG_WAIT_FOR_STYLES_TIMEOUT:
  367. if (frames_doc)
  368. RaiseCondition(frames_doc->WaitForStylesTimedOut());
  369. break;
  370. case MSG_INLINE_REPLACE:
  371. UrlImageContentProvider::ResetAndRestartImageFromID(par1);
  372. break;
  373. case MSG_URL_LOADING_FAILED:
  374. case MSG_HEADER_LOADED:
  375. case MSG_URL_DATA_LOADED:
  376. case MSG_NOT_MODIFIED:
  377. case MSG_ALL_LOADED:
  378. case MSG_MULTIPART_RELOAD:
  379. RaiseCondition(HandleLoading(msg, (URL_ID) par1, par2));
  380. if (msg == MSG_URL_DATA_LOADED)
  381. window->HandleDocumentProgress(0);
  382. break;
  383. case MSG_URL_MOVED:
  384. {
  385. URL moved_to = current_url_reserved->GetAttribute(URL::KMovedToURL, FALSE);
  386. if (current_url_reserved->Id() == static_cast<URL_ID>(par1) && !moved_to.IsEmpty())
  387. {
  388. OP_ASSERT(moved_to.Id() == static_cast<URL_ID>(par2));
  389. // Unlock previous url and lock the new url
  390. current_url_reserved.SetURL(moved_to);
  391. if (security_check_callback && !queue_messages)
  392. {
  393. OP_ASSERT(!security_check_callback->m_suspended || security_check_callback->m_done);
  394. SecCheckRes res = InitiateSecurityCheck(moved_to, referrer_url);
  395. if (res == SEC_CHECK_STARTED)
  396. {
  397. // Enables queuing. This message is added first on the queue and reprocessed or dropped depending on the outcome.
  398. security_check_callback->PrepareForSuspendingRedirect();
  399. }
  400. else if (res != SEC_CHECK_ALLOWED)
  401. break;
  402. }
  403. RaiseCondition(HandleLoading(msg, (URL_ID) par1, par2));
  404. }
  405. break;
  406. }
  407. case MSG_URL_LOAD_NOW:
  408. // par1: url id
  409. // par2: user_initiated
  410. LoadPendingUrl((URL_ID) par1, !!par2);
  411. break;
  412. #ifdef SHORTCUT_ICON_SUPPORT
  413. case MSG_FAVICON_TIMEOUT:
  414. // par1: url id
  415. if (frames_doc)
  416. frames_doc->FaviconTimedOut(par1);
  417. break;
  418. #endif // SHORTCUT_ICON_SUPPORT
  419. case MSG_START_REFRESH_LOADING:
  420. Refresh(static_cast<URL_ID>(par1));
  421. break;
  422. case MSG_DOC_DELAYED_ACTION:
  423. OnDelayedActionMessageReceived();
  424. break;
  425. case MSG_HISTORY_CLEANUP:
  426. HistoryCleanup();
  427. break;
  428. case MSG_DOCHAND_PROCESS_QUEUED_MESSAGE:
  429. {
  430. QueuedMessageElm *elm = (QueuedMessageElm *) queued_messages.First();
  431. if (security_check_callback && elm->msg == MSG_URL_MOVED)
  432. {
  433. if (!security_check_callback->m_suspended)
  434. {
  435. // A queued redirect that hasn't yet been security checked.
  436. SecCheckRes res = InitiateSecurityCheck(elm->target_url, referrer_url);
  437. if (res == SEC_CHECK_STARTED)
  438. {
  439. // Async check. The message is left at the head of the queue.
  440. // It will be reprocessed or dropped depending on the outcome.
  441. security_check_callback->PrepareForSuspendingRedirect();
  442. }
  443. if (res != SEC_CHECK_ALLOWED)
  444. break;
  445. }
  446. OP_ASSERT(!security_check_callback->m_suspended || security_check_callback->m_allowed);
  447. security_check_callback->Reset();
  448. }
  449. // We don't want our call to HandleLoading here to queue the message, do we?
  450. queue_messages = FALSE;
  451. if (elm)
  452. {
  453. RaiseCondition(HandleLoading(elm->msg, elm->url_id, elm->user_data));
  454. elm->Out();
  455. OP_DELETE(elm);
  456. }
  457. if (queued_messages.Empty())
  458. {
  459. if (GetLoadStatus() == NOT_LOADING)
  460. StopLoading(FALSE);
  461. }
  462. else
  463. {
  464. queue_messages = TRUE;
  465. mh->PostMessage(MSG_DOCHAND_PROCESS_QUEUED_MESSAGE, 0, 0);
  466. }
  467. break;
  468. }
  469. #ifdef _WML_SUPPORT_
  470. case MSG_WML_REFRESH:
  471. oom = OpStatus::IsMemoryError(UpdateCurrentDoc(FALSE, FALSE, !!par2));
  472. break;
  473. #endif // _WML_SUPPORT_
  474. #ifdef TRUST_RATING
  475. case MSG_TRUST_CHECK_DONE:
  476. {
  477. ServerTrustChecker* checker = (ServerTrustChecker*)m_active_trust_checks.First();
  478. while (checker)
  479. {
  480. ServerTrustChecker* next_checker = (ServerTrustChecker*)checker->Suc();
  481. if (checker->GetId() == (UINT)par1)
  482. {
  483. checker->Out();
  484. OP_DELETE(checker);
  485. }
  486. checker = next_checker;
  487. }
  488. }
  489. break;
  490. #endif // TRUST_RATING
  491. #ifdef WEBFEEDS_DISPLAY_SUPPORT
  492. case MSG_DISPLAY_WEBFEED:
  493. {
  494. URL feed_output;
  495. URL ref_url;
  496. OpFeed* feed = g_webfeeds_api->GetFeedById(par1);
  497. if (feed)
  498. {
  499. OP_STATUS status = feed->WriteFeed(feed_output, TRUE);
  500. if (OpStatus::IsSuccess(status))
  501. {
  502. OpenURLOptions options;
  503. options.entered_by_user = WasEnteredByUser;
  504. options.es_terminated = TRUE; // Why? To make it faster?
  505. OpenURL(feed_output, DocumentReferrer(ref_url), FALSE/*check_if_expired*/, FALSE/*reload*/, options);
  506. }
  507. else if (OpStatus::IsMemoryError(status))
  508. oom = TRUE;
  509. }
  510. break;
  511. }
  512. #endif // WEBFEEDS_DISPLAY_SUPPORT
  513. #if defined _SSL_SUPPORT_ && !defined _EXTERNAL_SSL_SUPPORT_ && !defined _CERTICOM_SSL_SUPPORT_
  514. case MSG_DOCHAND_CERTIFICATE_INSTALL:
  515. if (ssl_certificate_installer)
  516. {
  517. /* This is the "finished message," so it'd better be finished. */
  518. OP_ASSERT(ssl_certificate_installer->Finished());
  519. if (!ssl_certificate_installer->InstallSuccess())
  520. {
  521. queue_messages = FALSE;
  522. StopLoading(FALSE);
  523. queued_messages.Clear();
  524. }
  525. else if (!queued_messages.Empty())
  526. mh->PostMessage(MSG_DOCHAND_PROCESS_QUEUED_MESSAGE, 0, 0);
  527. else
  528. {
  529. queue_messages = FALSE;
  530. StopLoading(FALSE);
  531. }
  532. OP_DELETE(ssl_certificate_installer);
  533. ssl_certificate_installer = NULL;
  534. }
  535. break;
  536. #endif // _SSL_SUPPORT_ && !_EXTERNAL_SSL_SUPPORT_ && !_CERTICOM_SSL_SUPPORT_
  537. default:
  538. OP_ASSERT(FALSE); // Huh?
  539. }
  540. if (oom)
  541. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  542. }
  543. void
  544. DocumentManager::SetLoadStat(DM_LoadStat value)
  545. {
  546. if (load_stat == NOT_LOADING && value != NOT_LOADING)
  547. {
  548. current_url_used.SetURL(current_url);
  549. #ifdef SHORTCUT_ICON_SUPPORT
  550. if (!GetFrame())
  551. /* This call moved from Window::StartProgressDisplay() to here. We
  552. call StartProgressDisplay() when we start loading any document in
  553. the window as well as when we start loading some unrelated inline
  554. in any document in the window. This only happens when we start
  555. loading a document in the top frame. */
  556. OpStatus::Ignore(window->SetWindowIcon(NULL));
  557. #endif // SHORTCUT_ICON_SUPPORT
  558. if (vis_dev)
  559. vis_dev->StartLoading();
  560. activity_loading.Begin();
  561. }
  562. else if (load_stat != NOT_LOADING && value == NOT_LOADING)
  563. {
  564. current_url_used.UnsetURL();
  565. current_url_reserved.UnsetURL();
  566. user_initiated_loading = FALSE;
  567. activity_loading.Cancel();
  568. if (history_state_doc_elm)
  569. {
  570. if (history_state_doc_elm == current_doc_elm)
  571. {
  572. SetCurrentURL(history_state_doc_elm->GetUrl(), FALSE);
  573. history_state_doc_elm->Doc()->ClearAuxUrlToHandleLoadingMessagesFor();
  574. current_url_is_inline_feed = FALSE;
  575. }
  576. history_state_doc_elm = NULL;
  577. }
  578. #ifdef WEB_HANDLERS_SUPPORT
  579. if (action_locked)
  580. {
  581. action_locked = FALSE;
  582. SetAction(VIEWER_NOT_DEFINED);
  583. }
  584. #endif // WEB_HANDLERS_SUPPORT
  585. }
  586. if (load_stat != DOC_CREATED && value == DOC_CREATED)
  587. {
  588. FramesDocElm* fdelm = frame;
  589. while (fdelm)
  590. {
  591. fdelm->SetOnLoadCalled(FALSE);
  592. fdelm->SetOnLoadReady(FALSE);
  593. fdelm = fdelm->Parent();
  594. }
  595. if (vis_dev)
  596. vis_dev->DocCreated();
  597. }
  598. load_stat = value;
  599. }
  600. int
  601. DocumentManager::GetNextHistoryNumber(BOOL is_replace, BOOL &replaced_empty)
  602. {
  603. BOOL do_replace = is_replace;
  604. replaced_empty = FALSE;
  605. if (!do_replace && current_doc_elm)
  606. {
  607. if (!current_doc_elm->HasPreceding() && !current_doc_elm->IsScriptGeneratedDocument())
  608. {
  609. URL url = current_doc_elm->GetUrl();
  610. if (url.Type() == URL_NULL_TYPE || url.Type() == URL_JAVASCRIPT || url.GetAttribute(URL::KName).Compare("about:blank") == 0)
  611. do_replace = TRUE;
  612. }
  613. if (!do_replace && current_doc_elm->ReplacedEmptyPosition())
  614. {
  615. if (request_thread_info.type == ES_THREAD_INLINE_SCRIPT)
  616. do_replace = TRUE;
  617. else if (request_thread_info.type == ES_THREAD_EVENT && request_thread_info.data.event.is_window_event &&
  618. (request_thread_info.data.event.type == ONLOAD || request_thread_info.data.event.type == DOMCONTENTLOADED))
  619. do_replace = TRUE;
  620. }
  621. replaced_empty = do_replace;
  622. }
  623. int next_history_number;
  624. if (use_history_number != -1)
  625. next_history_number = use_history_number;
  626. else if (current_doc_elm && do_replace)
  627. next_history_number = current_doc_elm->Number();
  628. else
  629. next_history_number = window->SetNewHistoryNumber();
  630. use_history_number = -1;
  631. return next_history_number;
  632. }
  633. void
  634. DocumentManager::InsertHistoryElement(DocListElm *element)
  635. {
  636. /* This is not supported! */
  637. OP_ASSERT(element->Doc());
  638. DocListElm *existing;
  639. for (existing = FirstDocListElm(); existing; existing = existing->Suc())
  640. if (existing->Number() > element->Number())
  641. {
  642. element->Precede(existing);
  643. break;
  644. }
  645. if (!existing)
  646. element->Into(&doc_list);
  647. if (frame && element == doc_list.First())
  648. {
  649. /* When we're inserting the first element into the history in a frame or
  650. iframe, it should always get the history number of the parent
  651. document, since otherwise this frame would be empty at history
  652. positions from the parent document's to this element's. */
  653. DocListElm *parent = parent_doc->GetDocManager()->current_doc_elm;
  654. while (parent->Pred() && parent->Pred()->Doc() == parent->Doc())
  655. parent = parent->Pred();
  656. element->SetNumber(parent->Number());
  657. }
  658. if (!has_posted_history_cleanup)
  659. if (DocListElm *previous = element->Pred())
  660. if (previous->Number() == element->Number())
  661. {
  662. has_posted_history_cleanup = TRUE;
  663. mh->PostMessage(MSG_HISTORY_CLEANUP, 0, 0);
  664. }
  665. }
  666. static const OpMessage docman_messages[] =
  667. {
  668. MSG_HANDLE_BY_OPERA,
  669. MSG_REFLOW_DOCUMENT,
  670. MSG_WAIT_FOR_STYLES_TIMEOUT,
  671. MSG_INLINE_REPLACE,
  672. MSG_URL_LOADING_FAILED,
  673. MSG_HEADER_LOADED,
  674. MSG_URL_DATA_LOADED,
  675. MSG_ALL_LOADED,
  676. MSG_NOT_MODIFIED,
  677. MSG_MULTIPART_RELOAD,
  678. MSG_URL_LOAD_NOW,
  679. MSG_URL_MOVED,
  680. #ifdef TRUST_RATING
  681. MSG_TRUST_CHECK_DONE,
  682. #endif // TRUST_RATING
  683. #ifdef WEBFEEDS_DISPLAY_SUPPORT
  684. MSG_DISPLAY_WEBFEED,
  685. #endif // WEBFEEDS_DISPLAY_SUPPORT
  686. #ifdef SHORTCUT_ICON_SUPPORT
  687. MSG_FAVICON_TIMEOUT,
  688. #endif // SHORTCUT_ICON_SUPPORT
  689. MSG_START_REFRESH_LOADING,
  690. MSG_DOC_DELAYED_ACTION,
  691. MSG_HISTORY_CLEANUP,
  692. #ifdef _WML_SUPPORT_
  693. MSG_WML_REFRESH,
  694. #endif // _WML_SUPPORT_
  695. #if defined _SSL_SUPPORT_ && !defined _EXTERNAL_SSL_SUPPORT_ && !defined _CERTICOM_SSL_SUPPORT_
  696. MSG_DOCHAND_CERTIFICATE_INSTALL,
  697. #endif // _SSL_SUPPORT_ && !_EXTERNAL_SSL_SUPPORT_ && !_CERTICOM_SSL_SUPPORT_
  698. #ifdef COOKIE_WARNING_SUPPORT
  699. MSG_COOKIE_SET,
  700. #endif // COOKIE_WARNING_SUPPORT
  701. MSG_DOCHAND_PROCESS_QUEUED_MESSAGE
  702. };
  703. OP_STATUS
  704. DocumentManager::UpdateCallbacks(BOOL is_active)
  705. {
  706. if (!is_active)
  707. {
  708. if (has_set_callbacks)
  709. {
  710. has_set_callbacks = FALSE;
  711. mh->UnsetCallBacks(this);
  712. return mh->SetCallBack(this, MSG_HISTORY_CLEANUP, 0);
  713. }
  714. }
  715. else if (!has_set_callbacks)
  716. {
  717. RETURN_IF_ERROR(mh->SetCallBackList(this, 0, docman_messages, sizeof docman_messages / sizeof docman_messages[0]));
  718. has_set_callbacks = TRUE;
  719. }
  720. return OpStatus::OK;
  721. }
  722. void
  723. DocumentManager::HistoryCleanup()
  724. {
  725. if (has_posted_history_cleanup)
  726. {
  727. BOOL try_again_later = FALSE;
  728. for (DocListElm *element = FirstDocListElm(); element; element = element->Suc())
  729. if (DocListElm *previous = element->Pred())
  730. if (previous->Number() == element->Number())
  731. {
  732. // Same number -> unreachable in history since it was
  733. // replaced by another document at the same history position.
  734. if (previous->Doc()->IsESGeneratingDocument())
  735. {
  736. // Quite likely the generated document wants to access the
  737. // dom environment of this document so we keep it around even
  738. // though it's not reachable in history
  739. continue;
  740. }
  741. if (previous->Doc()->IsESActive(FALSE))
  742. {
  743. // Running scripts right now so can't really
  744. // delete it. A thing of the past?
  745. try_again_later = TRUE;
  746. continue;
  747. }
  748. if (previous == history_state_doc_elm)
  749. {
  750. history_state_doc_elm = NULL;
  751. }
  752. previous->Out();
  753. OP_DELETE(previous);
  754. }
  755. if (try_again_later)
  756. mh->PostMessage(MSG_HISTORY_CLEANUP, 0, 0);
  757. else
  758. has_posted_history_cleanup = FALSE;
  759. }
  760. }
  761. void
  762. DocumentManager::DropCurrentLoadingOrigin()
  763. {
  764. if (current_loading_origin)
  765. {
  766. current_loading_origin->DecRef();
  767. current_loading_origin = NULL;
  768. }
  769. }
  770. DocumentOrigin*
  771. DocumentManager::CreateOriginFromLoadingState()
  772. {
  773. DocumentOrigin* origin;
  774. if (current_loading_origin)
  775. {
  776. origin = current_loading_origin;
  777. current_loading_origin = NULL;
  778. // Not calling IncRef and DecRef since the number of references stay the same.
  779. }
  780. else if (!IsURLSuitableSecurityContext(current_url) && (referrer_url.origin || IsURLSuitableSecurityContext(referrer_url.url)))
  781. {
  782. if (referrer_url.origin)
  783. {
  784. origin = referrer_url.origin;
  785. origin->IncRef();
  786. }
  787. else
  788. origin = DocumentOrigin::Make(referrer_url.url);
  789. }
  790. else
  791. origin = DocumentOrigin::Make(current_url);
  792. return origin;
  793. }
  794. void
  795. DocumentManager::SetCurrentURL(const URL &url, BOOL moved)
  796. {
  797. // Keep the origin if this is a redirect to something with no
  798. // intrinsic domain.
  799. if (!moved || IsURLSuitableSecurityContext(url))
  800. DropCurrentLoadingOrigin();
  801. current_url = url;
  802. if (load_stat != NOT_LOADING)
  803. {
  804. URL_InUse temporary_use(current_url);
  805. current_url_used.SetURL(current_url);
  806. }
  807. }
  808. URL
  809. DocumentManager::GetCurrentDocURL()
  810. {
  811. return current_doc_elm ? current_doc_elm->GetUrl() : URL();
  812. }
  813. DocumentReferrer DocumentManager::GenerateReferrerURL()
  814. {
  815. if (!IsURLSuitableSecurityContext(current_url))
  816. {
  817. DocumentReferrer referrer = current_doc_elm ? current_doc_elm->GetReferrerUrl() : referrer_url;
  818. if (!referrer.IsEmpty())
  819. return referrer;
  820. }
  821. return DocumentReferrer(current_url);
  822. }
  823. DocumentManager::DocumentManager(Window* win, FramesDocElm* frm, FramesDocument* pdoc)
  824. : window(win),
  825. mh(NULL),
  826. frame(frm),
  827. parent_doc(pdoc),
  828. vis_dev(NULL),
  829. current_doc_elm(NULL),
  830. history_len(0),
  831. queue_messages(FALSE),
  832. load_stat(NOT_LOADING),
  833. current_url_is_inline_feed(FALSE),
  834. current_loading_origin(NULL),
  835. send_to_server(TRUE),
  836. current_action(VIEWER_NOT_DEFINED),
  837. current_application(NULL),
  838. url_replace_on_command(FALSE),
  839. user_auto_reload(FALSE),
  840. reload(FALSE),
  841. was_reloaded(FALSE),
  842. were_inlines_reloaded(FALSE),
  843. were_inlines_requested_conditionally(TRUE),
  844. redirect(FALSE),
  845. replace(FALSE),
  846. scroll_to_fragment_in_document_finished(FALSE),
  847. load_image_only(FALSE),
  848. save_image_only(FALSE),
  849. is_handling_message(FALSE),
  850. is_clearing(FALSE),
  851. has_posted_history_cleanup(FALSE),
  852. has_set_callbacks(FALSE),
  853. error_page_shown(FALSE),
  854. use_history_number(-1),
  855. use_current_doc(FALSE),
  856. reload_document(FALSE),
  857. conditionally_request_document(TRUE),
  858. reload_inlines(FALSE),
  859. conditionally_request_inlines(TRUE),
  860. check_expiry(CHECK_EXPIRY_NEVER),
  861. history_walk(DM_NOT_HIST),
  862. pending_refresh_id(0),
  863. waiting_for_refresh_id(0),
  864. start_navigation_time_ms(0.0),
  865. restart_parsing(FALSE),
  866. pending_viewport_restore(FALSE),
  867. #ifdef _PRINT_SUPPORT_
  868. print_doc(NULL),
  869. print_preview_doc(NULL),
  870. print_vd(NULL),
  871. print_preview_vd(NULL),
  872. #endif // _PRINT_SUPPORT_
  873. pending_url_user_initiated(FALSE),
  874. user_started_loading(FALSE),
  875. user_initiated_loading(FALSE),
  876. check_url_access(TRUE),
  877. #ifdef _WML_SUPPORT_
  878. wml_context(NULL),
  879. #endif // _WML_SUPPORT_
  880. dom_environment(NULL),
  881. es_pending_unload(FALSE),
  882. es_terminating_action(NULL),
  883. request_thread_info(ES_THREAD_EMPTY),
  884. history_state_doc_elm(NULL),
  885. history_traverse_pending_delta(0),
  886. m_waiting_for_online_url(NULL),
  887. #if defined _SSL_SUPPORT_ && !defined _EXTERNAL_SSL_SUPPORT_ && !defined _CERTICOM_SSL_SUPPORT_
  888. ssl_certificate_installer(NULL),
  889. #endif // _SSL_SUPPORT_ && !_EXTERNAL_SSL_SUPPORT_ && !_CERTICOM_SSL_SUPPORT_
  890. is_delayed_action_msg_posted(FALSE),
  891. #ifdef TRUST_RATING
  892. m_next_checker_id(1),
  893. #endif // TRUST_RATING
  894. #ifdef CLIENTSIDE_STORAGE_SUPPORT
  895. m_storage_manager(NULL),
  896. #endif // CLIENTSIDE_STORAGE_SUPPORT
  897. activity_loading(ACTIVITY_DOCMAN),
  898. activity_refresh(ACTIVITY_METAREFRESH),
  899. #ifdef SCOPE_PROFILER
  900. m_timeline(NULL),
  901. #endif // SCOPE_PROFILER
  902. #ifdef WEB_HANDLERS_SUPPORT
  903. action_locked(FALSE),
  904. skip_protocol_handler_check(FALSE),
  905. #endif // WEB_HANDLERS_SUPPORT
  906. waiting_for_document_ready(FALSE),
  907. security_check_callback(NULL)
  908. #ifdef DOM_LOAD_TV_APP
  909. , whitelist(NULL)
  910. #endif
  911. {
  912. OP_ASSERT(win);
  913. }
  914. DocumentManager::~DocumentManager()
  915. {
  916. Clear();
  917. #ifdef _WML_SUPPORT_
  918. if (wml_context)
  919. {
  920. wml_context->DecRef();
  921. wml_context = NULL;
  922. }
  923. #endif // _WML_SUPPORT_
  924. DOM_ProxyEnvironment::Destroy(dom_environment);
  925. #ifdef TRUST_RATING
  926. m_active_trust_checks.Clear();
  927. #endif // TRUST_RATING
  928. #ifdef CLIENTSIDE_STORAGE_SUPPORT
  929. if (m_storage_manager)
  930. {
  931. m_storage_manager->Release();
  932. m_storage_manager = NULL;
  933. }
  934. #endif //CLIENTSIDE_STORAGE_SUPPORT
  935. DropCurrentLoadingOrigin();
  936. #ifdef WIC_USE_DOWNLOAD_CALLBACK
  937. while (current_download_vector.GetCount())
  938. {
  939. current_download_vector.Get(0)->ReleaseDocument();
  940. }
  941. #endif
  942. if (mh)
  943. {
  944. mh->UnsetCallBacks(this);
  945. OP_DELETE(mh);
  946. }
  947. if (security_check_callback)
  948. {
  949. if (!security_check_callback->m_suspended || security_check_callback->m_done)
  950. OP_DELETE(security_check_callback);
  951. else
  952. security_check_callback->Invalidate();
  953. }
  954. queued_messages.Clear();
  955. }
  956. OP_STATUS DocumentManager::Construct()
  957. {
  958. OP_ASSERT(!mh);
  959. mh = OP_NEW(MessageHandler, (window, this));
  960. if (!mh)
  961. return OpStatus::ERR_NO_MEMORY;
  962. return UpdateCallbacks(TRUE);
  963. }
  964. int DocumentManager::GetSubWinId()
  965. {
  966. return frame ? frame->GetSubWinId() : -1;
  967. }
  968. void DocumentManager::RemoveFromHistory(int from, BOOL unlink)
  969. {
  970. /* Our current history position's number and the window's idea of what the
  971. current history number ought to be seem to be in conflict if this test
  972. fails, and the window is trying to remove the current history position.
  973. This is really bad and should be investigated immediately. */
  974. OP_ASSERT(!current_doc_elm || current_doc_elm->Number() < from);
  975. while (DocListElm *dle = (DocListElm *) doc_list.Last())
  976. if (dle->HasPreceding() && dle->Number() >= from)
  977. /* This history position begins after the point we're removing,
  978. so we should remove it. */
  979. if (!dle->GetOwnsDoc() || dle->Doc()->Free(FALSE, FramesDocument::FREE_VERY_IMPORTANT))
  980. RemoveElementFromHistory(dle, unlink);
  981. else
  982. /* The document couldn't be freed, usually because there is some
  983. script currently running in it, affecting the next history
  984. position, which typically will be the current one. */
  985. break;
  986. else
  987. {
  988. /* DocumentManager::InsertHistoryElement() (and anyone else
  989. manipulating the history list) should make sure this is true,
  990. that is, that child history lists start at the same history
  991. number as their parent document. */
  992. OP_ASSERT(dle->Number() < from);
  993. dle->Doc()->RemoveFromHistory(from);
  994. return;
  995. }
  996. }
  997. void DocumentManager::RemoveUptoHistory(int to, BOOL unlink)
  998. {
  999. /* Our current history position's number and the window's idea of what the
  1000. current history number ought to be seem to be in conflict if this test
  1001. fails. This is really bad and should be investigated immediately. */
  1002. OP_ASSERT(!current_doc_elm || current_doc_elm->Number() >= to || !current_doc_elm->Suc());
  1003. while (DocListElm *dle = (DocListElm *) doc_list.First())
  1004. if (dle->Suc() && dle->Suc()->Number() <= to)
  1005. /* If there is a later history position that doesn't begin beyond
  1006. the point we're removing, we can safely remove this one. */
  1007. if (dle->MaybeReassignDocOwnership() || dle->Doc()->Free(FALSE, FramesDocument::FREE_VERY_IMPORTANT))
  1008. RemoveElementFromHistory(dle, unlink);
  1009. else
  1010. /* The document couldn't be freed, usually because there is some
  1011. script currently running in it, affecting the next history
  1012. position, which typically will be the current one. */
  1013. break;
  1014. else
  1015. {
  1016. /* If there's a group of elements that have the same number, all but
  1017. the last are dead and about to be removed by a call to
  1018. DocumentManager::HistoryCleanup(), but only if they continue to
  1019. have a number equal to the others. Since we will reset the
  1020. "real" element's number to 'to', we also want to reset all the
  1021. dead ones' numbers to 'to'. And we also want to skip to the last
  1022. one, since calling Doc()->RemoveUptoHistory() is only relevant on
  1023. that one (but is really important, on the other hand.) */
  1024. while (dle->Suc() && dle->Suc()->Number() == dle->Number())
  1025. {
  1026. dle->SetNumber(to);
  1027. dle = dle->Suc();
  1028. }
  1029. /* Otherwise, update this history position's number to the point of
  1030. removal (it'll be the first history number after the operation,
  1031. and if this document manager was at all affected, which it
  1032. obviously was since we got called, its first history position
  1033. should now start at the globally first history number.) */
  1034. dle->SetNumber(to);
  1035. dle->Doc()->RemoveUptoHistory(to);
  1036. return;
  1037. }
  1038. }
  1039. BOOL HistoryNumberExists(FramesDocument *top_doc, int number, BOOL forward)
  1040. {
  1041. DocListElm *tmp_elm = top_doc->GetDocManager()->CurrentDocListElm();
  1042. while (tmp_elm && tmp_elm->Number() != number && NULL == tmp_elm->Doc()->GetHistoryElmAt(number, forward))
  1043. tmp_elm = forward ? tmp_elm->Suc() : tmp_elm->Pred();
  1044. return tmp_elm != NULL;
  1045. }
  1046. void DocumentManager::RemoveElementFromHistory(int pos, BOOL unlink)
  1047. {
  1048. DocListElm* dle = LastDocListElm();
  1049. while (dle && dle->Number() > pos)
  1050. dle = dle->Pred();
  1051. if (!dle || dle->Number() != pos)
  1052. return;
  1053. RemoveElementFromHistory(dle, unlink);
  1054. }
  1055. void DocumentManager::RemoveElementFromHistory(DocListElm *dle, BOOL unlink, BOOL update_current_history_pos)
  1056. {
  1057. DocListElm* prev = dle->Pred();
  1058. history_len--;
  1059. // set the new current_history_number
  1060. if (update_current_history_pos && dle->Number() == window->GetCurrentHistoryPos())
  1061. window->SetCurrentHistoryPosOnly(prev ? prev->Number() : 0);
  1062. FramesDocument *top_doc = window->GetCurrentDoc();
  1063. if (top_doc)
  1064. {
  1065. // set the new history_max when removing last history element
  1066. if (!dle->Suc() && dle->Number() == window->GetHistoryMax())
  1067. {
  1068. int candidate_max = dle->Number() - 1;
  1069. while (candidate_max > 0 && !HistoryNumberExists(top_doc, candidate_max, FALSE))
  1070. candidate_max--;
  1071. window->SetMaxHistoryPos(candidate_max);
  1072. }
  1073. // set the new history_min when removing first history element, unless it was also the last
  1074. if (!dle->Pred() && dle->Number() == window->GetHistoryMin() && dle->Number() < window->GetHistoryMax())
  1075. {
  1076. int candidate_min = dle->Number() + 1;
  1077. while (candidate_min < window->GetHistoryMax() && !HistoryNumberExists(top_doc, candidate_min, TRUE))
  1078. candidate_min++;
  1079. window->SetMinHistoryPos(candidate_min);
  1080. }
  1081. }
  1082. if (current_doc_elm == dle)
  1083. {
  1084. // embrowser specific: clear current document if removed from history
  1085. if (dle->Doc())
  1086. {
  1087. dle->Doc()->Undisplay();
  1088. }
  1089. current_doc_elm = NULL;
  1090. }
  1091. if (history_state_doc_elm == dle)
  1092. {
  1093. history_state_doc_elm = NULL;
  1094. }
  1095. dle->Out();
  1096. if (unlink)
  1097. /* DocListElm::ReplaceDoc() will have set 'dle->doc' to NULL if other
  1098. history positions shared document with 'dle'. In that case trying to
  1099. put 'dle' back into the history later will fail silently. */
  1100. dle->Into(&unlinked_doc_list);
  1101. else
  1102. OP_DELETE(dle);
  1103. }
  1104. #ifdef DOCHAND_HISTORY_MANIPULATION_SUPPORT
  1105. void DocumentManager::InsertElementInHistory(int pos, DocListElm * doc_elm)
  1106. {
  1107. BOOL raise_OOM_condition = FALSE;
  1108. if( doc_elm )
  1109. {
  1110. FramesDocument * doc = doc_elm->Doc();
  1111. if (doc == doc->GetTopDocument())
  1112. window->SetType(doc->Type());
  1113. if (!doc)
  1114. /* Documentless DocListElm:s are not supported. Leave 'doc_elm' in
  1115. unlinked_doc_list (where it ought to have been) from where it
  1116. will be deleted in our destructor. Since there was no document
  1117. the history position is light-weight. */
  1118. return;
  1119. if (unlinked_doc_list.HasLink(doc_elm))
  1120. doc_elm->Out();
  1121. else
  1122. {
  1123. /* Either this history position is already in our history, or it
  1124. comes from a different history list. Either way, we don't
  1125. support it. */
  1126. OP_ASSERT(FALSE);
  1127. return;
  1128. }
  1129. InsertHistoryElement(doc_elm);
  1130. int win_history_num = window->GetCurrentHistoryNumber();
  1131. if (pos == win_history_num)
  1132. if( window->UpdateTitle() == OpStatus::ERR_NO_MEMORY )
  1133. raise_OOM_condition = TRUE;
  1134. while(doc_elm)
  1135. {
  1136. doc_elm->SetNumber(pos++);
  1137. doc_elm = doc_elm->Suc();
  1138. }
  1139. DocListElm *elm = FirstDocListElm();
  1140. while(elm)
  1141. {
  1142. if(doc == elm->Doc())
  1143. {
  1144. elm->SetOwnsDoc(TRUE); // The first element that refers to the document owns it
  1145. elm = elm->Suc();
  1146. break;
  1147. }
  1148. elm = elm->Suc();
  1149. }
  1150. while(elm)
  1151. {
  1152. if(doc == elm->Doc())
  1153. {
  1154. elm->SetOwnsDoc(FALSE); // No one else does
  1155. }
  1156. elm = elm->Suc();
  1157. }
  1158. history_len++;
  1159. }
  1160. if (raise_OOM_condition)
  1161. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  1162. }
  1163. #endif // DOCHAND_HISTORY_MANIPULATION_SUPPORT
  1164. void DocumentManager::HandleErrorUrl()
  1165. {
  1166. SetLoadStat(NOT_LOADING);
  1167. SetUserAutoReload(FALSE);
  1168. SetReload(FALSE);
  1169. SetRedirect(FALSE);
  1170. SetReplace(FALSE);
  1171. SetUseHistoryNumber(-1);
  1172. SetAction(VIEWER_NOT_DEFINED);
  1173. FramesDocument* current_doc = GetCurrentDoc();
  1174. if (current_doc)
  1175. SetCurrentURL(current_doc->GetURL(), FALSE);
  1176. else
  1177. SetCurrentURL(URL(), FALSE);
  1178. EndProgressDisplay();
  1179. if (es_pending_unload)
  1180. OpStatus::Ignore(ESCancelPendingUnload());
  1181. }
  1182. DocumentManager* DocumentManager::GetDocManagerById(int sub_win_id) const
  1183. {
  1184. if (FramesDocument* doc = GetCurrentDoc())
  1185. return doc->GetDocManagerById(sub_win_id);
  1186. else
  1187. return NULL;
  1188. }
  1189. void DocumentManager::ESGeneratingDocument(ES_Thread *generating_thread, BOOL is_reload, DocumentOrigin* caller_origin)
  1190. {
  1191. activity_loading.Begin();
  1192. StoreRequestThreadInfo(generating_thread);
  1193. BOOL replaced_empty;
  1194. ES_Thread *migrate = NULL;
  1195. int current_history_number = window->GetCurrentHistoryNumber();
  1196. int next_history_number = GetNextHistoryNumber(is_reload, replaced_empty);
  1197. FramesDocument *prev_frames_doc;
  1198. FramesDocument *frames_doc;
  1199. DocListElm *prev_doc_elm;
  1200. URL referrer_url;
  1201. prev_frames_doc = current_doc_elm->Doc();
  1202. #ifdef DOCUMENT_EDIT_SUPPORT
  1203. BOOL inherit_design_mode = prev_frames_doc->GetDesignMode();
  1204. #endif // DOCUMENT_EDIT_SUPPORT
  1205. frames_doc = OP_NEW(FramesDocument, (this, current_url, caller_origin, GetSubWinId()));
  1206. if (!frames_doc ||
  1207. frames_doc->CreateESEnvironment(TRUE) == OpStatus::ERR_NO_MEMORY ||
  1208. frames_doc->ESStartGeneratingDocument(generating_thread) == OpStatus::ERR_NO_MEMORY)
  1209. {
  1210. OP_DELETE(frames_doc);
  1211. goto cleanup_oom;
  1212. }
  1213. prev_doc_elm = current_doc_elm;
  1214. // store the scroll position in DocListElm
  1215. StoreViewport(prev_doc_elm);
  1216. current_doc_elm = OP_NEW(DocListElm, (current_url, frames_doc, TRUE, next_history_number, GetNextDocListElmId()));
  1217. if (!current_doc_elm)
  1218. {
  1219. current_doc_elm = prev_doc_elm;
  1220. OP_DELETE(frames_doc);
  1221. goto cleanup_oom;
  1222. }
  1223. current_doc_elm->SetReferrerUrl(prev_frames_doc, ShouldSendReferrer());
  1224. InsertHistoryElement(current_doc_elm);
  1225. current_doc_elm->SetScriptGeneratedDocument();
  1226. if (replaced_empty)
  1227. current_doc_elm->SetReplacedEmptyPosition();
  1228. if (prev_doc_elm->Doc()->Undisplay() == OpStatus::ERR_NO_MEMORY)
  1229. goto cleanup_oom;
  1230. if (SignalOnNewPage(VIEWPORT_CHANGE_REASON_NEW_PAGE))
  1231. waiting_for_document_ready = TRUE;
  1232. // Both for javascript urls and ordinary document.open, make sure to signal the loading of a new document to the UI.
  1233. OpStatus::Ignore(window->StartProgressDisplay(TRUE, FALSE /* bResetSecurityState */, !!GetParentDoc() /* bSubResourcesOnly */));
  1234. prev_frames_doc->ESSetGeneratedDocument(frames_doc);
  1235. frames_doc->ESSetReplacedDocument(prev_frames_doc);
  1236. if (generating_thread->GetScheduler() == prev_frames_doc->GetESScheduler())
  1237. {
  1238. migrate = generating_thread;
  1239. }
  1240. else
  1241. {
  1242. ES_Thread *interrupted_thread = generating_thread->GetInterruptedThread();
  1243. while (interrupted_thread)
  1244. {
  1245. ES_ThreadScheduler *scheduler = interrupted_thread->GetScheduler();
  1246. if (interrupted_thread->GetBlockType() == ES_BLOCK_FOREIGN_THREAD && scheduler == prev_frames_doc->GetESScheduler())
  1247. {
  1248. migrate = interrupted_thread;
  1249. break;
  1250. }
  1251. interrupted_thread = interrupted_thread->GetInterruptedThread();
  1252. }
  1253. }
  1254. if (migrate)
  1255. {
  1256. /* The script is replacing its own document. */
  1257. OP_STATUS status = frames_doc->ConstructDOMEnvironment();
  1258. if (status == OpStatus::ERR)
  1259. {
  1260. /* It's quite odd if we decide scripting is disabled in the new
  1261. document, since it has the same URL as the previous one, in the
  1262. same window, and we obviously think scripting is enabled in the
  1263. previous one. */
  1264. OP_ASSERT(FALSE);
  1265. StopLoading(TRUE);
  1266. return;
  1267. }
  1268. if (OpStatus::IsMemoryError(status) || OpStatus::IsMemoryError(frames_doc->GetESScheduler()->MigrateThread(migrate)))
  1269. goto cleanup_oom;
  1270. }
  1271. if (prev_frames_doc->SetAsCurrentDoc(FALSE) == OpStatus::ERR_NO_MEMORY ||
  1272. frames_doc->SetAsCurrentDoc(TRUE) == OpStatus::ERR_NO_MEMORY)
  1273. goto cleanup_oom;
  1274. #ifdef DOCUMENT_EDIT_SUPPORT
  1275. if (inherit_design_mode && OpStatus::IsMemoryError(frames_doc->SetEditable(FramesDocument::DESIGNMODE)))
  1276. goto cleanup_oom;
  1277. #endif // DOCUMENT_EDIT_SUPPORT
  1278. SetLoadStatus(DOC_CREATED);
  1279. if (current_history_number != next_history_number)
  1280. history_len++;
  1281. frames_doc->ClearScreenOnLoad();
  1282. CheckOnNewPageReady();
  1283. return;
  1284. cleanup_oom:
  1285. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  1286. StopLoading(TRUE);
  1287. }
  1288. void
  1289. DocumentManager::ESGeneratingDocumentFinished()
  1290. {
  1291. if (!has_posted_history_cleanup)
  1292. {
  1293. has_posted_history_cleanup = TRUE;
  1294. mh->PostMessage(MSG_HISTORY_CLEANUP, 0, 0);
  1295. }
  1296. activity_loading.Cancel();
  1297. }
  1298. /* virtual */ OP_STATUS
  1299. DocumentManager::GetRealWindow(DOM_Object *&window)
  1300. {
  1301. FramesDocument* frames_doc = GetCurrentDoc();
  1302. if (!frames_doc)
  1303. {
  1304. RETURN_IF_ERROR(CreateInitialEmptyDocument(FALSE, FALSE));
  1305. frames_doc = GetCurrentDoc();
  1306. OP_ASSERT(frames_doc);
  1307. }
  1308. else if (!frames_doc->IsCurrentDoc())
  1309. return OpStatus::ERR;
  1310. if (!frames_doc->GetLogicalDocument())
  1311. {
  1312. DM_LoadStat old_load_stat = load_stat;
  1313. load_stat = DOC_CREATED;
  1314. RETURN_IF_ERROR(frames_doc->CheckSource()); // CheckSource is dangerous... It skips necessary tests and makes us for instance parse and show binary data that should have been downloaded or put into a plugin. This should be removed I think.
  1315. load_stat = old_load_stat;
  1316. }
  1317. if (!frames_doc->GetDOMEnvironment())
  1318. {
  1319. URL host = frames_doc->GetOrigin()->security_context;
  1320. BOOL pref_js_enabled = g_pcjs->GetIntegerPref(PrefsCollectionJS::EcmaScriptEnabled, host);
  1321. BOOL ecmascript_enabled = DOM_Environment::IsEnabled(frames_doc, pref_js_enabled);
  1322. if (!ecmascript_enabled)
  1323. return OpStatus::ERR;
  1324. }
  1325. RETURN_IF_ERROR(frames_doc->ConstructDOMEnvironment());
  1326. window = frames_doc->GetJSWindow();
  1327. return OpStatus::OK;
  1328. }
  1329. OP_STATUS DocumentManager::ConstructDOMProxyEnvironment()
  1330. {
  1331. if (!dom_environment)
  1332. {
  1333. RETURN_IF_ERROR(DOM_ProxyEnvironment::Create(dom_environment));
  1334. dom_environment->SetRealWindowProvider(this);
  1335. }
  1336. return OpStatus::OK;
  1337. }
  1338. OP_STATUS DocumentManager::GetJSWindow(DOM_Object *&window, ES_Runtime *origining_runtime)
  1339. {
  1340. RETURN_IF_ERROR(ConstructDOMProxyEnvironment());
  1341. return dom_environment->GetProxyWindow(window, origining_runtime);
  1342. }
  1343. BOOL DocumentManager::HasJSWindow()
  1344. {
  1345. return dom_environment != NULL;
  1346. }
  1347. void DocumentManager::UpdateCurrentJSWindow()
  1348. {
  1349. if (dom_environment)
  1350. /* This triggers a call to the GetRealWindow callback the next
  1351. time the proxy window is used. */
  1352. dom_environment->Update();
  1353. }
  1354. void DocumentManager::ESSetPendingUnload(ES_OpenURLAction *action)
  1355. {
  1356. es_pending_unload = action ? TRUE : FALSE;
  1357. es_terminating_action = action;
  1358. }
  1359. OP_STATUS DocumentManager::ESSendPendingUnload(BOOL check_if_inline_expired, BOOL use_plugin)
  1360. {
  1361. OP_STATUS status = es_terminating_action->SendPendingUnload(check_if_inline_expired, use_plugin);
  1362. es_pending_unload = FALSE;
  1363. es_terminating_action = NULL;
  1364. return status;
  1365. }
  1366. OP_STATUS DocumentManager::ESCancelPendingUnload()
  1367. {
  1368. OP_STATUS status = es_terminating_action->CancelPendingUnload();
  1369. es_pending_unload = FALSE;
  1370. es_terminating_action = NULL;
  1371. return status;
  1372. }
  1373. OP_STATUS DocumentManager::PutHistoryState(ES_PersistentValue *data, const uni_char *title, URL &url, BOOL create_new /*= TRUE*/)
  1374. {
  1375. OP_ASSERT(current_doc_elm);
  1376. URL previous_url = current_doc_elm->GetUrl();
  1377. // Copy the security state from the original URL. The state shouldn't change because the
  1378. // new URL must be on the same protocol and host.
  1379. RETURN_IF_ERROR(url.SetAttribute(URL::KSecurityStatus, previous_url.GetAttribute(URL::KSecurityStatus)));
  1380. RETURN_IF_ERROR(url.SetAttribute(URL::KSecurityText, previous_url.GetAttribute(URL::KSecurityText)));
  1381. if (create_new)
  1382. {
  1383. DocumentReferrer referrer(current_doc_elm->Doc());
  1384. RETURN_IF_ERROR(AddNewHistoryPosition(url, referrer, -1, title, TRUE, FALSE, current_doc_elm->Doc()));
  1385. }
  1386. else
  1387. {
  1388. RETURN_IF_ERROR(current_doc_elm->SetTitle(title));
  1389. current_doc_elm->SetUrl(url);
  1390. }
  1391. current_doc_elm->SetData(data);
  1392. if (GetLoadStatus() == NOT_LOADING) // Otherwise the current document loading will be broken
  1393. SetCurrentURL(url, FALSE);
  1394. else
  1395. {
  1396. if (current_doc_elm->Doc()->GetAuxUrlToHandleLoadingMessagesFor().IsEmpty())
  1397. current_doc_elm->Doc()->SetAuxUrlToHandleLoadingMessagesFor(current_doc_elm->Doc()->GetURL());
  1398. history_state_doc_elm = current_doc_elm;
  1399. }
  1400. // Set URLs in HLDocProfile
  1401. current_doc_elm->Doc()->GetHLDocProfile()->OnPutHistoryState(url);
  1402. // Set URL in FramesDocument as well and notify UI about the change.
  1403. current_doc_elm->Doc()->SetUrl(current_doc_elm->GetUrl());
  1404. current_doc_elm->Doc()->NotifyUrlChanged(current_doc_elm->GetUrl());
  1405. return OpStatus::OK;
  1406. }
  1407. OP_STATUS
  1408. DocumentManager::CreateInitialEmptyDocument(BOOL for_javascript_url, BOOL prevent_early_onload,
  1409. BOOL use_opera_blanker/* = FALSE */)
  1410. {
  1411. OP_ASSERT(!GetCurrentDoc());
  1412. // There is no document here yet (probably loading) so we'll make a
  1413. // about:blank (or opera:blanker if 'use_opera_blanker' is TRUE)
  1414. // placeholder so that scripts have something to play with. The current
  1415. // state (what we're loading etc) shouldn't change.
  1416. // The correct context id should be assigned to the blank url anyway,
  1417. // since it may be used as a parent url somewhere else.
  1418. const char* blank_url_name = use_opera_blanker ? "opera:blanker" : "about:blank";
  1419. URL blank_url;
  1420. if (GetFrame())
  1421. {
  1422. // Effectively "inherit" the context id from what we consider the parent url of the blank url should be.
  1423. blank_url = g_url_api->GetURL(GetFrame()->GetParentFramesDoc()->GetURL(), blank_url_name);
  1424. }
  1425. else
  1426. {
  1427. URL opener_url = GetWindow()->GetOpenerSecurityContext();
  1428. if (opener_url.IsEmpty())
  1429. blank_url = g_url_api->GetURL(blank_url_name, GetWindow()->GetUrlContextId());
  1430. else
  1431. blank_url = g_url_api->GetURL(opener_url, blank_url_name);
  1432. }
  1433. if (load_stat == WAIT_FOR_HEADER && current_url == blank_url)
  1434. {
  1435. // Ah, we have an empty document loading. Speed it up.
  1436. HandleHeaderLoaded(blank_url.Id(TRUE), FALSE);
  1437. OP_ASSERT(GetCurrentDoc());
  1438. OP_ASSERT(current_url == blank_url);
  1439. OP_ASSERT(load_stat == NOT_LOADING || load_stat == DOC_CREATED);
  1440. HandleDataLoaded(blank_url.Id(TRUE));
  1441. OP_ASSERT(GetCurrentDoc());
  1442. OP_ASSERT(current_url == blank_url);
  1443. OP_ASSERT(load_stat == NOT_LOADING || load_stat == DOC_CREATED); // Most likely DOC_CREATED since we haven't done a Reflow
  1444. }
  1445. if (!GetCurrentDoc())
  1446. {
  1447. DocumentOrigin* origin = NULL;
  1448. if (GetFrame())
  1449. origin = GetFrame()->GetParentFramesDoc()->GetMutableOrigin();
  1450. else if (current_loading_origin)
  1451. origin = current_loading_origin;
  1452. else if (referrer_url.origin)
  1453. origin =referrer_url.origin;
  1454. else if (GetWindow()->GetOpenerOrigin())
  1455. origin = GetWindow()->GetOpenerOrigin();
  1456. if (origin)
  1457. origin->IncRef();
  1458. else
  1459. {
  1460. origin = DocumentOrigin::Make(blank_url);
  1461. if (!origin)
  1462. return OpStatus::ERR_NO_MEMORY;
  1463. }
  1464. FramesDocument* doc = OP_NEW(FramesDocument, (this, blank_url, origin, GetSubWinId(), FALSE));
  1465. origin->DecRef();
  1466. origin = NULL;
  1467. if (!doc)
  1468. return OpStatus::ERR_NO_MEMORY;
  1469. int history_number;
  1470. if (FramesDocElm* fdelm = GetFrame())
  1471. history_number = fdelm->GetParentFramesDoc()->GetDocManager()->CurrentDocListElm()->Number();
  1472. else
  1473. {
  1474. BOOL replaced_empty;
  1475. history_number = GetNextHistoryNumber(FALSE, replaced_empty);
  1476. }
  1477. DocListElm* new_dle = OP_NEW(DocListElm, (blank_url, doc, TRUE, history_number, GetNextDocListElmId()));
  1478. if (!new_dle)
  1479. {
  1480. OP_DELETE(doc);
  1481. return OpStatus::ERR_NO_MEMORY;
  1482. }
  1483. new_dle->SetIsReplaceable();
  1484. SetUseHistoryNumber(history_number);
  1485. InsertHistoryElement(new_dle);
  1486. current_doc_elm = new_dle;
  1487. doc->SetWaitForJavascriptURL(for_javascript_url);
  1488. // SetAsCurrentDoc doesn't like to be called unless the url in
  1489. // DocumentManager matches it so we temporarily change the url
  1490. // but have to restore it afterwards so that the current
  1491. // operation in DocumentManager can continue.
  1492. URL temp = current_url;
  1493. current_url = blank_url;
  1494. RETURN_IF_ERROR(doc->SetAsCurrentDoc(TRUE));
  1495. if (load_stat != NOT_LOADING)
  1496. current_url = temp;
  1497. OP_ASSERT(GetCurrentDoc() == doc);
  1498. // We might actually be loading something already and this document shouldn't
  1499. // interfere with that loading, just insert itself first in the list
  1500. DM_LoadStat old_load_stat = load_stat;
  1501. load_stat = DOC_CREATED;
  1502. RETURN_IF_ERROR(doc->CheckSource()); // CheckSource is in general wrong and dangerous but in this case we knows that the document is a simple about:blank and we will do the right thing with it.
  1503. load_stat = old_load_stat;
  1504. }
  1505. FramesDocument* doc = GetCurrentDoc();
  1506. OP_ASSERT(doc);
  1507. if (prevent_early_onload)
  1508. doc->SetInhibitOnLoadAboutBlank(TRUE);
  1509. OP_ASSERT(doc->GetLogicalDocument());
  1510. OP_ASSERT(doc->GetLogicalDocument()->IsParsed());
  1511. RETURN_IF_MEMORY_ERROR(doc->Reflow(FALSE, TRUE, FALSE, FALSE)); // Not happy about this at all, but without it IsLoaded() will not be TRUE
  1512. OP_ASSERT(doc->GetLogicalDocument()->IsLoaded());
  1513. if (prevent_early_onload)
  1514. doc->SetInhibitOnLoadAboutBlank(FALSE);
  1515. return OpStatus::OK;
  1516. }
  1517. static OP_STATUS GetURLFragment(URL url, OpString& decoded_fragment, OpString& original_fragment)
  1518. {
  1519. RETURN_IF_ERROR(url.GetAttribute(URL::KUniFragment_Name, original_fragment));
  1520. RETURN_IF_ERROR(decoded_fragment.Set(original_fragment));
  1521. uni_char* frag = decoded_fragment.CStr();
  1522. // Bug 292214 - url fragments are not url decoded when read with this API so we have to do it ourself
  1523. if (frag && *frag)
  1524. {
  1525. // Need to url decode it
  1526. // new_fragment_id is new_fragment.CStr()
  1527. UriUnescape::ReplaceChars(frag, UriUnescape::NonCtrlAndEsc);
  1528. }
  1529. return OpStatus::OK;
  1530. }
  1531. OP_STATUS
  1532. DocumentManager::UpdateAction(const uni_char* &app)
  1533. {
  1534. ViewAction action = GetAction();
  1535. if (action == VIEWER_NOT_DEFINED)
  1536. {
  1537. RETURN_IF_MEMORY_ERROR(g_viewers->GetAppAndAction(current_url, action, app));
  1538. #ifdef CONTENT_DISPOSITION_ATTACHMENT_FLAG
  1539. if (current_url.GetAttribute(URL::KUsedContentDispositionAttachment))
  1540. {
  1541. DocumentOrigin* unique_origin = DocumentOrigin::MakeUniqueOrigin(current_url.GetContextId(), TRUE);
  1542. if (!unique_origin)
  1543. return OpStatus::ERR_NO_MEMORY;
  1544. if (current_loading_origin)
  1545. current_loading_origin->DecRef();
  1546. current_loading_origin = unique_origin;
  1547. # ifdef _BITTORRENT_SUPPORT_
  1548. if (!(current_url.ContentType() == URL_P2P_BITTORRENT && action != VIEWER_OPERA))
  1549. # endif // _BITTORRENT_SUPPORT_
  1550. {
  1551. action = VIEWER_ASK_USER;
  1552. }
  1553. }
  1554. # ifdef _BITTORRENT_SUPPORT_
  1555. if(!g_pcnet->GetIntegerPref(PrefsCollectionNetwork::EnableBitTorrent)
  1556. && current_url.ContentType() == URL_P2P_BITTORRENT && action == VIEWER_OPERA)
  1557. {
  1558. // if BitTorrent is turned off but we still have Opera set as viewer, we need a kludge to workaround
  1559. // being asked to download it with Opera's BT anyway
  1560. action = VIEWER_ASK_USER;
  1561. }
  1562. # endif // _BITTORRENT_SUPPORT_
  1563. #endif
  1564. // Some download dialogs for embedded content we want to supress
  1565. if (action == VIEWER_ASK_USER && GetFrame())
  1566. {
  1567. if (HTML_Element* embedding_element = GetFrame()->GetHtmlElement())
  1568. {
  1569. #ifdef SVG_SUPPORT
  1570. // never-stop-loading on unknown svg document inlines (e.g <animation>, <foreignObject>)
  1571. if (embedding_element->GetNsType() == NS_SVG)
  1572. {
  1573. action = VIEWER_IGNORE_URL;
  1574. }
  1575. #endif // SVG_SUPPORT
  1576. if (embedding_element->IsMatchingType(HE_OBJECT, NS_HTML) ||
  1577. embedding_element->IsMatchingType(HE_EMBED, NS_HTML))
  1578. {
  1579. // Was probably meant as a plugin and nobody will be happy to see
  1580. // a download dialog. See DSK-160957
  1581. // This can be made smarter for sure, but we'll need more experience
  1582. // with the real world use of objects for downloads first.
  1583. action = VIEWER_IGNORE_URL;
  1584. }
  1585. }
  1586. }
  1587. SetAction(action);
  1588. }
  1589. return OpStatus::OK;
  1590. }
  1591. OP_STATUS DocumentManager::SetCurrentDoc(BOOL check_if_inline_expired, BOOL use_plugin, BOOL create_document, BOOL is_user_initiated)
  1592. {
  1593. OP_PROBE3(OP_PROBE_DOCUMENTMANAGER_SETCURRENTDOC);
  1594. OP_STATUS status = OpStatus::OK;
  1595. BOOL raise_OOM_condition = FALSE;
  1596. URLStatus url_stat = current_url.Status(TRUE);
  1597. if (!create_document && !use_current_doc && (url_stat == URL_EMPTY || current_url.IsEmpty()))
  1598. {
  1599. HandleErrorUrl();
  1600. return status;
  1601. }
  1602. else if (!create_document && !use_current_doc && url_stat == URL_UNLOADED)
  1603. {
  1604. StopLoading(FALSE);
  1605. return status;
  1606. }
  1607. else
  1608. {
  1609. #ifndef NO_URL_OPERA
  1610. BOOL download_doc = (current_url.Type() == URL_OPERA && current_url.GetAttribute(URL::KName).CompareI("opera:download") == 0);
  1611. #endif // !NO_URL_OPERA
  1612. URLContentType type = current_url.ContentType();
  1613. if (!create_document &&
  1614. !use_current_doc &&
  1615. #ifndef NO_URL_OPERA
  1616. !download_doc &&
  1617. #endif // !NO_URL_OPERA
  1618. !use_plugin &&
  1619. type != URL_HTML_CONTENT &&
  1620. type != URL_XML_CONTENT &&
  1621. #ifdef _WML_SUPPORT_
  1622. type != URL_WML_CONTENT &&
  1623. type != URL_WBMP_CONTENT &&
  1624. #endif
  1625. #ifdef SVG_SUPPORT
  1626. type != URL_SVG_CONTENT &&
  1627. #endif
  1628. type != URL_TEXT_CONTENT &&
  1629. #ifdef HAS_ATVEF_SUPPORT // Reckognize TV:
  1630. type != URL_TV_CONTENT &&
  1631. #endif // HAS_ATVEF_SUPPORT
  1632. type != URL_CSS_CONTENT &&
  1633. type != URL_X_JAVASCRIPT &&
  1634. !imgManager->IsImage(type) &&
  1635. #ifdef _SSL_SUPPORT_
  1636. type != URL_PFX_CONTENT &&
  1637. type != URL_X_X509_USER_CERT &&
  1638. type != URL_X_X509_CA_CERT &&
  1639. type != URL_X_PEM_FILE &&
  1640. #endif
  1641. #ifdef _ISHORTCUT_SUPPORT
  1642. type != URL_ISHORTCUT_CONTENT &&
  1643. #endif//_ISHORTCUT_SUPPORT
  1644. #ifdef SUPPORT_AUTO_PROXY_CONFIGURATION
  1645. type != URL_PAC_CONTENT &&
  1646. #endif // SUPPORT_AUTO_PROXY_CONFIGURATION
  1647. #ifdef MHTML_ARCHIVE_REDIRECT_SUPPORT
  1648. type != URL_MHTML_ARCHIVE &&
  1649. #endif
  1650. #ifdef APPLICATION_CACHE_SUPPORT
  1651. type != URL_MANIFEST_CONTENT &&
  1652. #endif // APPLICATION_CACHE_SUPPORT
  1653. #ifdef MEDIA_HTML_SUPPORT
  1654. !g_media_module.IsMediaPlayableUrl(current_url) &&
  1655. #endif // MEDIA_HTML_SUPPORT
  1656. type != URL_MIME_CONTENT)
  1657. {
  1658. HandleErrorUrl();
  1659. return status;
  1660. }
  1661. BOOL use_existing_doc = FALSE, replaced_empty;
  1662. window->SetIsImplicitSuppressWindow(!!current_url.GetAttribute(URL::KSuppressScriptAndEmbeds, TRUE));
  1663. window->SetIsScriptableWindow(!current_url.GetAttribute(URL::KSuppressScriptAndEmbeds, TRUE));
  1664. FramesDocument* doc = NULL;
  1665. DocListElm* prev_doc_elm = current_doc_elm;
  1666. if (prev_doc_elm && use_history_number == -1)
  1667. {
  1668. if (prev_doc_elm->IsReplaceable())
  1669. /* Previous (that is, current) history position is "replaceable"
  1670. (that is, should be replaced,) so reuse its number and let
  1671. the grim reaper (that is, HistoryCleanup) take it later. */
  1672. SetUseHistoryNumber(prev_doc_elm->Number());
  1673. }
  1674. int current_history_number = window->GetCurrentHistoryNumber();
  1675. int next_history_number = GetNextHistoryNumber(replace, replaced_empty);
  1676. // DSK-120311: When moving to a new document in the history, the
  1677. // character encoding should reset to the default.
  1678. #ifdef RESET_ENCODING_ON_NEW_DOCUMENT
  1679. if (current_history_number != next_history_number && !GetWindow()->IsMailOrNewsfeedWindow())
  1680. {
  1681. #ifdef PREFS_HOSTOVERRIDE
  1682. // Check if the forced character encoding is overridden for
  1683. // this host.
  1684. const OpStringC force_encoding(g_pcdisplay->GetStringPref(PrefsCollectionDisplay::ForceEncoding, current_url));
  1685. if (force_encoding.HasContent())
  1686. {
  1687. // Convert to ASCII
  1688. char sbencoding[128]; /* ARRAY OK 2011-01-04 peter */
  1689. uni_cstrlcpy(sbencoding, force_encoding.CStr(), ARRAY_SIZE(sbencoding));
  1690. window->SetForceEncoding(sbencoding, TRUE);
  1691. }
  1692. else
  1693. #endif
  1694. {
  1695. window->SetForceEncoding(g_pcdisplay->GetForceEncoding(), TRUE);
  1696. }
  1697. }
  1698. #endif // RESET_ENCODING_ON_NEW_DOCUMENT
  1699. #if defined ERROR_PAGE_SUPPORT && defined TRUST_RATING
  1700. DocListElm* dle = (DocListElm*)doc_list.First();
  1701. if (!dle || next_history_number == dle->Number() && !dle->Pred())
  1702. {
  1703. if (current_url.Type() == URL_OPERA && current_url.GetAttribute(URL::KIsClickThroughPage))
  1704. {
  1705. OpString8 url_str;
  1706. OP_STATUS status;
  1707. if (OpStatus::IsSuccess(status = current_url.GetAttribute(URL::KName, url_str)))
  1708. {
  1709. if (url_str.Compare(PHISHING_WARNING_URL) == 0)
  1710. {
  1711. URL about_blank_url = g_url_api->GetURL("about:blank");
  1712. if (OpStatus::IsSuccess(status = AddNewHistoryPosition(about_blank_url, referrer_url, current_history_number, UNI_L("about:blank"))))
  1713. {
  1714. current_history_number = window->GetCurrentHistoryNumber();
  1715. next_history_number = window->SetNewHistoryNumber();
  1716. }
  1717. }
  1718. }
  1719. if (OpStatus::IsMemoryError(status))
  1720. raise_OOM_condition = TRUE;
  1721. }
  1722. }
  1723. #endif // defined ERROR_PAGE_SUPPORT && defined TRUST_RATING
  1724. CancelPendingViewportRestoration();
  1725. if (prev_doc_elm)
  1726. StoreViewport(prev_doc_elm);
  1727. #ifdef _PLUGIN_SUPPORT_
  1728. if (use_plugin)
  1729. type = URL_HTML_CONTENT;
  1730. #endif // _PLUGIN_SUPPORT_
  1731. if (current_doc_elm &&
  1732. current_doc_elm->Doc() &&
  1733. current_url.Type() != URL_JAVASCRIPT &&
  1734. current_history_number != next_history_number)
  1735. {
  1736. FramesDocument* curr_doc = current_doc_elm->Doc();
  1737. // Normally, when we get here we have stopped most of the
  1738. // document loading already. However, when dealing with
  1739. // response 204, No Content, we must not stop plugin
  1740. // streams, so they have been left running until now. At
  1741. // this point we know that we didn't receive a 204, so we
  1742. // can safely stop the plugin streams now.
  1743. OpStatus::Ignore(curr_doc->StopLoading(FALSE, FALSE, TRUE));
  1744. URL doc_url = curr_doc->GetURL();
  1745. if (doc_url == current_url && initial_request_url == current_url && current_url.RelName()
  1746. #ifdef _WML_CARD_SUPPORT_
  1747. && ((curr_doc->GetLogicalDocument() && !curr_doc->GetHLDocProfile()->IsWml())) // why this? /pw
  1748. #endif // _WML_CARD_SUPPORT_
  1749. )
  1750. {
  1751. // Same url. Jump inside existing document
  1752. use_existing_doc = TRUE;
  1753. doc = curr_doc;
  1754. }
  1755. }
  1756. if (!use_existing_doc)
  1757. {
  1758. if (GetWindow()->IsMailOrNewsfeedWindow())
  1759. {
  1760. if (prev_doc_elm && prev_doc_elm->Doc())
  1761. {
  1762. if (prev_doc_elm->Doc()->Undisplay() == OpStatus::ERR_NO_MEMORY) // always call Undisplay before SetAsCurrentDoc !!!
  1763. raise_OOM_condition = TRUE;
  1764. if (prev_doc_elm->Doc()->SetAsCurrentDoc(FALSE) == OpStatus::ERR_NO_MEMORY)
  1765. raise_OOM_condition = TRUE;
  1766. }
  1767. // always delete prev document(s) -- not using history anyway
  1768. RemoveUptoHistory(next_history_number);
  1769. current_doc_elm = prev_doc_elm = NULL;
  1770. }
  1771. DocumentOrigin* new_doc_origin;
  1772. if (current_loading_origin)
  1773. {
  1774. new_doc_origin = current_loading_origin;
  1775. current_loading_origin = NULL;
  1776. // Not calling IncRef and DecRef since the number of references stay the same.
  1777. }
  1778. else
  1779. new_doc_origin = DocumentOrigin::Make(current_url);
  1780. doc = NULL;
  1781. if (new_doc_origin)
  1782. {
  1783. doc = OP_NEW(FramesDocument, (this, current_url, new_doc_origin, GetSubWinId(), use_plugin, current_url_is_inline_feed));
  1784. new_doc_origin->DecRef();
  1785. new_doc_origin = NULL;
  1786. }
  1787. if (!doc)
  1788. raise_OOM_condition = TRUE;
  1789. }
  1790. if (doc)
  1791. {
  1792. current_doc_elm = OP_NEW(DocListElm, (current_url, doc, !use_existing_doc, next_history_number, GetNextDocListElmId()));
  1793. if (!current_doc_elm)
  1794. {
  1795. OP_DELETE((doc));
  1796. doc = NULL;
  1797. raise_OOM_condition = TRUE;
  1798. goto cleanup0;
  1799. }
  1800. InsertHistoryElement(current_doc_elm);
  1801. #ifdef DOCHAND_HISTORY_SAVE_ZOOM_LEVEL
  1802. if (!GetParentDoc())
  1803. window->SetScale(current_doc_elm->GetLastScale());
  1804. #endif // DOCHAND_HISTORY_SAVE_ZOOM_LEVEL
  1805. current_doc_elm->SetReferrerUrl(referrer_url, send_to_server);
  1806. if (replaced_empty)
  1807. current_doc_elm->SetReplacedEmptyPosition();
  1808. if (doc == doc->GetTopDocument() && !doc->GetURL().GetAttribute(URL::KIsGenerated))
  1809. window->SetType(doc->Type());
  1810. doc->SetStartNavigationTimeMS(start_navigation_time_ms);
  1811. if (use_existing_doc)
  1812. {
  1813. OpString original_fragment;
  1814. OpString decoded_fragment;
  1815. if (GetURLFragment(current_url, decoded_fragment, original_fragment) == OpStatus::ERR_NO_MEMORY ||
  1816. doc->SetRelativePos(original_fragment.CStr(), decoded_fragment.CStr()) == OpStatus::ERR_NO_MEMORY)
  1817. raise_OOM_condition = TRUE;
  1818. if (url_stat != URL_LOADING)
  1819. {
  1820. SetLoadStat(NOT_LOADING);
  1821. EndProgressDisplay();
  1822. }
  1823. if (doc->SetAsCurrentDoc(TRUE) == OpStatus::ERR_NO_MEMORY)
  1824. raise_OOM_condition = TRUE;
  1825. if (!raise_OOM_condition)
  1826. return status;
  1827. else
  1828. goto cleanup0;
  1829. }
  1830. if (prev_doc_elm && prev_doc_elm->Doc())
  1831. {
  1832. if (prev_doc_elm->Doc()->Undisplay() == OpStatus::ERR_NO_MEMORY) // always call Undisplay before SetAsCurrentDoc !!!
  1833. raise_OOM_condition = TRUE;
  1834. if (prev_doc_elm->Doc()->SetAsCurrentDoc(FALSE) == OpStatus::ERR_NO_MEMORY)
  1835. raise_OOM_condition = TRUE;
  1836. g_memory_manager->CheckDocMemorySize();
  1837. FlushHTTPSFromHistory(prev_doc_elm, current_doc_elm);
  1838. }
  1839. if (SignalOnNewPage(VIEWPORT_CHANGE_REASON_NEW_PAGE))
  1840. waiting_for_document_ready = TRUE;
  1841. if( doc->SetAsCurrentDoc(TRUE) == OpStatus::ERR_NO_MEMORY )
  1842. raise_OOM_condition = TRUE;
  1843. if (GetFrame() && GetFrame()->GetParentFramesDoc()->GetFramesStacked())
  1844. {
  1845. FramesDocument* top_doc = GetFrame()->GetTopFramesDoc();
  1846. if (top_doc)
  1847. {
  1848. if (next_history_number > current_history_number)
  1849. top_doc->SetLoadingFrame(GetFrame());
  1850. }
  1851. }
  1852. OP_BOOLEAN res = OpStatus::OK;
  1853. doc->ClearScreenOnLoad();
  1854. #ifdef _WML_SUPPORT_
  1855. if (type == URL_WML_CONTENT || wml_context)
  1856. {
  1857. if (!wml_context)
  1858. {
  1859. if (WMLInit() == OpStatus::ERR_NO_MEMORY)
  1860. raise_OOM_condition = TRUE;
  1861. }
  1862. else
  1863. {
  1864. /* 10.4 Context Restrictions of WML 1.3:
  1865. * [...] Whenever a user agent navigates to a resource that was not the result of an interaction with
  1866. * the content in the current context, the user agent must establish another context for that navigation.
  1867. * The user agent may terminate the current context before establishing another one for the new
  1868. * navigation attempt.
  1869. */
  1870. if (wml_context->IsSet(WS_USERINIT))
  1871. {
  1872. if (wml_context->SetNewContext() == OpStatus::ERR_NO_MEMORY)
  1873. raise_OOM_condition = TRUE;
  1874. wml_context->SetStatusOff(WS_USERINIT);
  1875. }
  1876. if (wml_context->PreParse() == OpStatus::ERR_NO_MEMORY)
  1877. raise_OOM_condition = TRUE;
  1878. current_doc_elm->SetWmlContext(wml_context);
  1879. }
  1880. SetLoadStat(DOC_CREATED);
  1881. if ((res = doc->CheckSource()) == OpStatus::ERR_NO_MEMORY)
  1882. raise_OOM_condition = TRUE;
  1883. if (wml_context)
  1884. {
  1885. if (wml_context->IsSet(WS_NOACCESS))
  1886. {
  1887. StopLoading(FALSE, TRUE);
  1888. wml_context->DenyAccess();
  1889. if (prev_doc_elm)
  1890. {
  1891. int old_pos = current_doc_elm->Number();
  1892. SetCurrentHistoryPos(prev_doc_elm->Number(), TRUE, is_user_initiated);
  1893. RemoveFromHistory(old_pos, FALSE);
  1894. window->SetCurrentHistoryNumber(prev_doc_elm->Number());
  1895. }
  1896. else
  1897. Clear();
  1898. return raise_OOM_condition ? OpStatus::ERR_NO_MEMORY : status;
  1899. }
  1900. if (wml_context->IsSet(WS_CLEANHISTORY))
  1901. { // transition to another WML session
  1902. WMLDeWmlifyHistory();
  1903. wml_context->SetFirstInSession(next_history_number);
  1904. wml_context->SetStatusOff(WS_CLEANHISTORY);
  1905. }
  1906. else if (wml_context->IsSet(WS_GO | WS_NEWCONTEXT)) // new context -> new session
  1907. wml_context->SetFirstInSession(next_history_number);
  1908. }
  1909. }
  1910. else
  1911. #endif // _WML_SUPPORT_
  1912. if (GetLoadStatus() == DOC_CREATED) // See if we can build the document immediately
  1913. {
  1914. if (OpStatus::IsMemoryError((res = doc->CheckSource())))
  1915. raise_OOM_condition = TRUE;
  1916. }
  1917. if (history_len == 0 || current_history_number != next_history_number)
  1918. history_len++;
  1919. else if (prev_doc_elm && prev_doc_elm->Number() >= current_history_number)
  1920. {
  1921. if (prev_doc_elm == history_state_doc_elm)
  1922. {
  1923. history_state_doc_elm = NULL;
  1924. }
  1925. prev_doc_elm->Out();
  1926. OP_DELETE(prev_doc_elm);
  1927. }
  1928. if (FramesDocument::CheckOnLoad(doc) == OpStatus::ERR_NO_MEMORY)
  1929. raise_OOM_condition = TRUE;
  1930. OpStatus::Ignore(window->UpdateTitle());//Not critical
  1931. }
  1932. }
  1933. cleanup0:
  1934. if (raise_OOM_condition)
  1935. {
  1936. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  1937. StopLoading(TRUE, TRUE, TRUE);
  1938. status = OpStatus::ERR_NO_MEMORY;
  1939. }
  1940. CheckOnNewPageReady();
  1941. #ifdef QUICK
  1942. g_input_manager->UpdateAllInputStates();
  1943. #endif // QUICK
  1944. return status;
  1945. }
  1946. OP_STATUS DocumentManager::UpdateCurrentDoc(BOOL use_plugin, BOOL parsing_restarted, BOOL is_user_initiated)
  1947. {
  1948. OP_STATUS status = OpStatus::OK;
  1949. OpStatus::Ignore(status);
  1950. BOOL raise_OOM_condition = FALSE;
  1951. URLStatus url_stat = current_url.Status(TRUE);
  1952. if (url_stat == URL_UNLOADED)
  1953. return status;
  1954. if (url_stat == URL_EMPTY || current_url.IsEmpty())
  1955. {
  1956. HandleErrorUrl();
  1957. return status;
  1958. }
  1959. else
  1960. {
  1961. URLContentType type = current_url.ContentType();
  1962. if (!use_plugin &&
  1963. !imgManager->IsImage(type) &&
  1964. #ifdef HAS_ATVEF_SUPPORT
  1965. type != URL_TV_CONTENT &&
  1966. #endif // HAS_ATVEF_SUPPORT
  1967. type != URL_HTML_CONTENT &&
  1968. type != URL_XML_CONTENT &&
  1969. #ifdef _WML_SUPPORT_
  1970. type != URL_WML_CONTENT &&
  1971. #endif
  1972. #ifdef SVG_SUPPORT
  1973. type != URL_SVG_CONTENT &&
  1974. #endif
  1975. type != URL_TEXT_CONTENT &&
  1976. type != URL_CSS_CONTENT &&
  1977. type != URL_X_JAVASCRIPT &&
  1978. GetLoadStatus() != WAIT_FOR_HEADER)
  1979. {
  1980. HandleErrorUrl();
  1981. return status;
  1982. }
  1983. if (current_doc_elm && current_doc_elm->Doc())
  1984. {
  1985. if (imgManager->IsImage(type))
  1986. UrlImageContentProvider::ResetImageFromUrl(current_url);
  1987. FramesDocument* doc = current_doc_elm->Doc();
  1988. /* Store the view port but not in a case history navigation took place as in such case
  1989. * the storing is done in SetCurrentHistoryPos(). Also do not store the view port when
  1990. * the parsing was restarted (due to a wrong charset used previously) as it may be invalid
  1991. * for the reparsed document.
  1992. */
  1993. if (!IsWalkingInHistory() && !parsing_restarted)
  1994. StoreViewport(current_doc_elm);
  1995. if (use_plugin || doc->GetURL().IsEmpty())
  1996. {
  1997. #ifdef _PLUGIN_SUPPORT_
  1998. if (use_plugin)
  1999. type = URL_HTML_CONTENT;
  2000. #endif // _PLUGIN_SUPPORT_
  2001. DocumentOrigin* origin = CreateOriginFromLoadingState();
  2002. doc = NULL;
  2003. if (origin)
  2004. {
  2005. doc = OP_NEW(FramesDocument, (this, current_url, origin, GetSubWinId(), use_plugin));
  2006. origin->DecRef();
  2007. origin = NULL;
  2008. }
  2009. if (!doc)
  2010. {
  2011. raise_OOM_condition = TRUE;
  2012. goto cleanup2;
  2013. }
  2014. current_doc_elm->ReplaceDoc(doc);
  2015. if (doc->SetAsCurrentDoc(TRUE) == OpStatus::ERR_NO_MEMORY)
  2016. raise_OOM_condition = TRUE;
  2017. if (doc == doc->GetTopDocument())
  2018. window->SetType(doc->Type());
  2019. }
  2020. else if (use_current_doc)
  2021. doc->SetUrl(current_url);
  2022. else
  2023. {
  2024. if (doc->IsFrameDoc() && current_doc_elm->Number() > GetWindow()->GetCurrentHistoryPos())
  2025. {
  2026. GetWindow()->SetCurrentHistoryPos(current_doc_elm->Number(), FALSE, is_user_initiated);
  2027. GetWindow()->SetCheckHistory(TRUE);
  2028. }
  2029. DocumentOrigin* origin = CreateOriginFromLoadingState();
  2030. if (origin)
  2031. {
  2032. if (doc->ReloadedUrl(current_url, origin, parsing_restarted) == OpStatus::ERR_NO_MEMORY)
  2033. raise_OOM_condition = TRUE;
  2034. origin->DecRef();
  2035. URL_InUse temporary_url_use(current_url);
  2036. if (doc->SetAsCurrentDoc(TRUE) == OpStatus::ERR_NO_MEMORY)
  2037. raise_OOM_condition = TRUE;
  2038. /* Synchronize referrer of the current element also. */
  2039. CurrentDocListElm()->SetReferrerUrl(referrer_url, CurrentDocListElm()->ShouldSendReferrer());
  2040. }
  2041. else
  2042. raise_OOM_condition = TRUE;
  2043. }
  2044. #ifdef _WML_SUPPORT_
  2045. if (type == URL_WML_CONTENT || wml_context)
  2046. {
  2047. if (!wml_context)
  2048. {
  2049. if (WMLInit() == OpStatus::ERR_NO_MEMORY)
  2050. raise_OOM_condition = TRUE;
  2051. }
  2052. else if (wml_context->PreParse() == OpStatus::ERR_NO_MEMORY)
  2053. raise_OOM_condition = TRUE;
  2054. SetLoadStat(DOC_CREATED);
  2055. if (doc->CheckSource() == OpStatus::ERR_NO_MEMORY)
  2056. raise_OOM_condition = TRUE;
  2057. if (!doc->IsLoaded())
  2058. SetLoadStat(DOC_CREATED);
  2059. if (wml_context)
  2060. {
  2061. if( wml_context->IsSet(WS_NOACCESS) )
  2062. {
  2063. StopLoading(FALSE);
  2064. wml_context->DenyAccess();
  2065. return raise_OOM_condition ? OpStatus::ERR_NO_MEMORY : status;
  2066. }
  2067. if( wml_context->IsSet(WS_CLEANHISTORY) )
  2068. { // transition to another WML session
  2069. WMLDeWmlifyHistory();
  2070. wml_context->SetFirstInSession(current_doc_elm->Number());
  2071. wml_context->SetStatusOff(WS_CLEANHISTORY);
  2072. }
  2073. else if( wml_context->IsSet(WS_GO | WS_NEWCONTEXT) ) // new context -> new session
  2074. wml_context->SetFirstInSession(current_doc_elm->Number());
  2075. }
  2076. }
  2077. else
  2078. #endif // _WML_SUPPORT_
  2079. {
  2080. // This code is both used for "reload" and "reload from
  2081. // cache". In case of "reload from cache", the load_stat
  2082. // isn't updated yet.
  2083. SetLoadStat(DOC_CREATED);
  2084. were_inlines_reloaded = reload_inlines;
  2085. if (doc->CheckSource() == OpStatus::ERR_NO_MEMORY)
  2086. raise_OOM_condition = TRUE;
  2087. }
  2088. if (OpStatus::IsMemoryError(UpdateWindowHistoryAndTitle()))
  2089. raise_OOM_condition = TRUE;
  2090. return raise_OOM_condition ? OpStatus::ERR_NO_MEMORY : status;
  2091. }
  2092. }
  2093. cleanup2:
  2094. if (raise_OOM_condition)
  2095. {
  2096. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  2097. StopLoading(TRUE, TRUE, TRUE);
  2098. status = OpStatus::ERR_NO_MEMORY;
  2099. }
  2100. return status;
  2101. }
  2102. void DocumentManager::SetCurrentNew(DocListElm* prev_doc_elm, BOOL is_user_initiated)
  2103. {
  2104. URL start_url = current_doc_elm->GetUrl();
  2105. BOOL pref_frames_enabled = g_pcdisplay->GetIntegerPref(PrefsCollectionDisplay::FramesEnabled, start_url);
  2106. BOOL pref_always_reload_https_in_history = g_pcnet->GetIntegerPref(PrefsCollectionNetwork::AlwaysReloadHTTPSInHistory);
  2107. check_expiry = (CheckExpiryType) g_pcnet->GetIntegerPref(PrefsCollectionNetwork::CheckExpiryHistory);
  2108. BOOL raise_OOM_condition = FALSE;
  2109. error_page_shown = FALSE;
  2110. current_url.StopLoading(mh);
  2111. FramesDocument* prev_doc = prev_doc_elm ? prev_doc_elm->Doc() : NULL;
  2112. if (prev_doc)
  2113. {
  2114. URL prev_doc_url = prev_doc->GetURL();
  2115. if (current_url == prev_doc_url)
  2116. if (prev_doc->StopLoading(FALSE) == OpStatus::ERR_NO_MEMORY)
  2117. raise_OOM_condition = TRUE;
  2118. }
  2119. FramesDocument* doc = GetCurrentDoc();
  2120. if (!frame)
  2121. window->SetType(doc->Type());
  2122. #ifdef NEARBY_ELEMENT_DETECTION
  2123. window->SetElementExpander(NULL);
  2124. #endif // NEARBY_ELEMENT_DETECTION
  2125. BOOL show_img = window->ShowImages();
  2126. #ifdef SUPPORT_VISUAL_ADBLOCK
  2127. // cache the server name so it's faster to do a lookup to check if the content blocker is enabled or not
  2128. if(doc && !parent_doc)
  2129. if (ServerName *server_name = doc->GetURL().GetServerName())
  2130. window->SetContentBlockServerName(server_name);
  2131. #endif // SUPPORT_VISUAL_ADBLOCK
  2132. if (!GetWindow()->IsMailOrNewsfeedWindow())
  2133. {
  2134. // Bug#128887: When moving to a new document in the history, the
  2135. // character encoding should reset to the default.
  2136. // Check correctness
  2137. #ifdef PREFS_HOSTOVERRIDE
  2138. const OpStringC force_encoding(g_pcdisplay->GetStringPref(PrefsCollectionDisplay::ForceEncoding, start_url));
  2139. if (!force_encoding.IsEmpty())
  2140. {
  2141. char sbencoding[128]; // ARRAY OK 2008-02-28 jl
  2142. uni_cstrlcpy(sbencoding, force_encoding.CStr(), ARRAY_SIZE(sbencoding));
  2143. window->SetForceEncoding(sbencoding, TRUE);
  2144. }
  2145. else
  2146. #endif // PREFS_HOSTOVERRIDE
  2147. window->SetForceEncoding(g_pcdisplay->GetForceEncoding(), TRUE);
  2148. }
  2149. if (prev_doc_elm)
  2150. {
  2151. FramesDocument* pdoc = prev_doc_elm->Doc();
  2152. if (pdoc)
  2153. {
  2154. if (pdoc->Undisplay() == OpStatus::ERR_NO_MEMORY) // always call Undisplay before SetAsCurrentDoc !!!
  2155. raise_OOM_condition = TRUE;
  2156. StoreViewport(prev_doc_elm);
  2157. if (pdoc->SetAsCurrentDoc(FALSE) == OpStatus::ERR_NO_MEMORY)
  2158. raise_OOM_condition = TRUE;
  2159. URL_InUse url_anchor(current_doc_elm->GetUrl()); // Don't flush the url.
  2160. g_memory_manager->DisplayedDoc(doc); // Don't flush the document we're going to.
  2161. g_memory_manager->CheckDocMemorySize();
  2162. }
  2163. }
  2164. URL url = current_doc_elm->GetUrl();
  2165. SetCurrentURL(url, FALSE);
  2166. current_url_is_inline_feed = FALSE;
  2167. #ifdef TRUST_RATING
  2168. OP_STATUS status = CheckTrustRating(url);
  2169. if (status == OpStatus::ERR_NO_ACCESS)
  2170. return;
  2171. if (OpStatus::IsMemoryError(status))
  2172. raise_OOM_condition = TRUE;
  2173. #endif // TRUST_RATING
  2174. if (window->StartProgressDisplay(TRUE) == OpStatus::ERR_NO_MEMORY)
  2175. raise_OOM_condition = TRUE;
  2176. window->SetState(CLICKABLE);
  2177. BOOL clean_document = FALSE;
  2178. if (pref_frames_enabled)
  2179. {
  2180. // check if document is frames enabled but not formatted as
  2181. if (!doc->IsFrameDoc() && doc->IsFramesEnabledDoc())
  2182. clean_document = TRUE;
  2183. }
  2184. else if (doc->IsFrameDoc())
  2185. clean_document = TRUE;
  2186. if (clean_document)
  2187. {
  2188. doc->Clean();
  2189. doc->CleanESEnvironment(TRUE);
  2190. if (doc->CreateESEnvironment(TRUE) == OpStatus::ERR_NO_MEMORY)
  2191. raise_OOM_condition = TRUE;
  2192. }
  2193. #ifdef _WML_SUPPORT_
  2194. if (current_doc_elm && current_doc_elm->GetWmlContext())
  2195. {
  2196. if (wml_context != current_doc_elm->GetWmlContext())
  2197. {
  2198. if (wml_context)
  2199. wml_context->DecRef();
  2200. wml_context = current_doc_elm->GetWmlContext();
  2201. if (wml_context)
  2202. wml_context->IncRef();
  2203. }
  2204. }
  2205. #endif // _WML_SUPPRT_
  2206. BOOL reload_https = pref_always_reload_https_in_history && url.Type() == URL_HTTPS;
  2207. if (frame)
  2208. {
  2209. if (reload_https)
  2210. frame->Free(FALSE, FramesDocument::FREE_VERY_IMPORTANT);
  2211. BOOL visible_if_current = TRUE;
  2212. if (frame->SetAsCurrentDoc(TRUE, visible_if_current) == OpStatus::ERR_NO_MEMORY)
  2213. raise_OOM_condition = TRUE;
  2214. }
  2215. else
  2216. {
  2217. if (reload_https)
  2218. doc->Free(FALSE, FramesDocument::FREE_VERY_IMPORTANT);
  2219. if (doc->SetAsCurrentDoc(TRUE) == OpStatus::ERR_NO_MEMORY)
  2220. raise_OOM_condition = TRUE;
  2221. }
  2222. window->DocManager()->UpdateSecurityState(FALSE);
  2223. if (!frame)
  2224. {
  2225. if (OpStatus::IsMemoryError(UpdateWindowHistoryAndTitle()))
  2226. raise_OOM_condition = TRUE;
  2227. #ifdef SHORTCUT_ICON_SUPPORT
  2228. if (OpStatus::IsMemoryError(window->SetWindowIcon(doc->Icon())))
  2229. raise_OOM_condition = TRUE;
  2230. #endif // SHORTCUT_ICON_SUPPORT
  2231. }
  2232. if (url.Type() == URL_JAVASCRIPT)
  2233. {
  2234. if (!doc->GetLogicalDocument())
  2235. {
  2236. // Not sure this can happen anylonger, but... we do need a document for javascript urls to run in. Normally just an empty about:blank document.
  2237. OpenURLOptions options;
  2238. options.is_walking_in_history = TRUE;
  2239. options.user_initiated = is_user_initiated;
  2240. OpenURL(url, doc, FALSE/*check_if_expired*/, FALSE/*reload*/, options);
  2241. }
  2242. }
  2243. else if (!current_doc_elm->IsScriptGeneratedDocument())
  2244. {
  2245. URL_HistoryNormal loadpolicy;
  2246. loadpolicy.SetUserInitiated(is_user_initiated);
  2247. URL ref_url;
  2248. if (!current_doc_elm->GetReferrerUrl().origin ||
  2249. !current_doc_elm->GetReferrerUrl().origin->IsUniqueOrigin())
  2250. ref_url = current_doc_elm->GetReferrerUrl().url;
  2251. CommState cstate = url.LoadDocument(mh, ref_url, loadpolicy);
  2252. // this will be turned on here, and off when finishing loading
  2253. history_walk = (current_doc_elm && prev_doc_elm && current_doc_elm->Number() < prev_doc_elm->Number()) ? DM_HIST_BACK : DM_HIST_FORW;
  2254. if (cstate == COMM_LOADING)
  2255. {
  2256. // URL is cleared from cache and is now reloading. Clean document.
  2257. if (frame)
  2258. frame->Free(FALSE, FramesDocument::FREE_VERY_IMPORTANT);
  2259. else
  2260. doc->Free(FALSE, FramesDocument::FREE_VERY_IMPORTANT);
  2261. doc->ClearScreenOnLoad(TRUE);
  2262. if (raise_OOM_condition)
  2263. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  2264. SetUserAutoReload(FALSE);
  2265. SetReload(TRUE);
  2266. SetReloadFlags(TRUE, TRUE, FALSE, TRUE);
  2267. SetLoadStat(WAIT_FOR_HEADER);
  2268. /* On failure, rare race conditions may occur. Usually everything
  2269. works fine, though, so ignoring this error is quite safe. */
  2270. OpStatus::Ignore(current_url_reserved.SetURL(url));
  2271. return;
  2272. }
  2273. SetLoadStat(DOC_CREATED);
  2274. // Bug#87069: The document was in cache, make sure we set up the
  2275. // viewers and action accordingly.
  2276. const uni_char* app = NULL;
  2277. if (OpStatus::IsMemoryError(UpdateAction(app)))
  2278. raise_OOM_condition = TRUE;
  2279. URLContentType type = current_url.ContentType();
  2280. if (type == URL_UNKNOWN_CONTENT
  2281. || type == URL_UNDETERMINED_CONTENT)
  2282. {
  2283. current_url.SetAttribute(URL::KForceContentType, URL_TEXT_CONTENT);
  2284. }
  2285. }
  2286. if (doc->SetMode(show_img, window->LoadImages(), window->GetCSSMode(), check_expiry) == OpStatus::ERR_NO_MEMORY)
  2287. raise_OOM_condition = TRUE;
  2288. doc->RecalculateLayoutViewSize(TRUE);
  2289. if (doc->IsTopDocument())
  2290. {
  2291. double min_zoom = ZoomLevelNotSet;
  2292. double max_zoom = ZoomLevelNotSet;
  2293. double zoom = ZoomLevelNotSet;
  2294. BOOL user_zoomable = TRUE;
  2295. # ifdef CSS_VIEWPORT_SUPPORT
  2296. HLDocProfile* hld_prof = doc->GetHLDocProfile();
  2297. if (hld_prof)
  2298. {
  2299. CSSCollection* css_coll = hld_prof->GetCSSCollection();
  2300. CSS_Viewport* css_viewport = css_coll->GetViewport();
  2301. if (css_viewport->GetMinZoom() != CSS_VIEWPORT_ZOOM_AUTO)
  2302. min_zoom = css_viewport->GetMinZoom();
  2303. if (css_viewport->GetMaxZoom() != CSS_VIEWPORT_ZOOM_AUTO)
  2304. max_zoom = css_viewport->GetMaxZoom();
  2305. user_zoomable = css_viewport->GetUserZoom();
  2306. if (css_viewport->GetZoom() != CSS_VIEWPORT_ZOOM_AUTO)
  2307. zoom = css_viewport->GetZoom();
  2308. }
  2309. #endif // CSS_VIEWPORT_SUPPORT
  2310. ViewportController* controller = doc->GetWindow()->GetViewportController();
  2311. OpViewportInfoListener* info_listener = controller->GetViewportInfoListener();
  2312. OpViewportRequestListener* request_listener = controller->GetViewportRequestListener();
  2313. vis_dev->SetLayoutScale(window->GetTrueZoomBaseScale());
  2314. info_listener->OnZoomLevelLimitsChanged(controller, min_zoom, max_zoom, user_zoomable);
  2315. request_listener->OnZoomLevelChangeRequest(controller, zoom, 0, VIEWPORT_CHANGE_REASON_NEW_PAGE);
  2316. }
  2317. if (current_doc_elm->GetLastScale() != window->GetScale())
  2318. if (HTML_Element* root = doc->GetDocRoot())
  2319. root->RemoveCachedTextInfo(doc);
  2320. #ifdef DOCHAND_HISTORY_SAVE_ZOOM_LEVEL
  2321. if (!GetParentDoc())
  2322. window->SetScale(current_doc_elm->GetLastScale());
  2323. #endif // DOCHAND_HISTORY_SAVE_ZOOM_LEVEL
  2324. #ifdef _WML_SUPPORT_
  2325. if (url.ContentType() == URL_WML_CONTENT || wml_context)
  2326. {
  2327. if (!wml_context)
  2328. {
  2329. if (WMLInit() == OpStatus::ERR_NO_MEMORY)
  2330. raise_OOM_condition = TRUE;
  2331. }
  2332. else if (wml_context->PreParse() == OpStatus::ERR_NO_MEMORY)
  2333. raise_OOM_condition = TRUE;
  2334. if (prev_doc_elm && prev_doc_elm->Number() > current_doc_elm->Number())
  2335. wml_context->SetStatusOn(WS_ENTERBACK);
  2336. if (doc->CheckSource() == OpStatus::ERR_NO_MEMORY)
  2337. raise_OOM_condition = TRUE;
  2338. if (wml_context)
  2339. {
  2340. if (wml_context->IsSet(WS_NOACCESS))
  2341. {
  2342. history_walk = DM_NOT_HIST;
  2343. wml_context->DenyAccess();
  2344. StopLoading(FALSE);
  2345. return;
  2346. }
  2347. if (wml_context->IsSet(WS_CLEANHISTORY))
  2348. { // transition to another WML session
  2349. WMLDeWmlifyHistory();
  2350. wml_context->SetFirstInSession(window->SetNewHistoryNumber());
  2351. wml_context->SetStatusOff(WS_CLEANHISTORY);
  2352. }
  2353. else
  2354. if (wml_context->IsSet(WS_GO | WS_NEWCONTEXT)) // new context -> new session
  2355. wml_context->SetFirstInSession(window->SetNewHistoryNumber());
  2356. }
  2357. }
  2358. else
  2359. #endif // _WML_SUPPORT_
  2360. if (OpStatus::IsMemoryError(doc->CheckSource()))
  2361. raise_OOM_condition = TRUE;
  2362. if (doc->ReactivateDocument() == OpStatus::ERR_NO_MEMORY)
  2363. raise_OOM_condition = TRUE;
  2364. if (doc->IsLoaded())
  2365. {
  2366. SetLoadStat(NOT_LOADING);
  2367. SetAction(VIEWER_NOT_DEFINED);
  2368. EndProgressDisplay();
  2369. }
  2370. if (doc->IsParsed())
  2371. {
  2372. // update screen
  2373. GetVisualDevice()->UpdateAll();
  2374. }
  2375. if (!window->IsLoading())
  2376. window->GetMessageHandler()->PostMessage(MSG_UPDATE_PROGRESS_TEXT, 0, 0);
  2377. else
  2378. {
  2379. window->SetState(CLICKABLE);
  2380. if( window->SetProgressText(url, TRUE) == OpStatus::ERR_NO_MEMORY )
  2381. raise_OOM_condition = TRUE;
  2382. }
  2383. history_walk = DM_NOT_HIST;
  2384. if (raise_OOM_condition)
  2385. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  2386. }
  2387. BOOL DocumentManager::IsCurrentDocTheSameAt(int position)
  2388. {
  2389. DocListElm* doc_elm = current_doc_elm;
  2390. FramesDocument* frames_doc = GetCurrentDoc();
  2391. if (doc_elm == NULL || frames_doc == NULL)
  2392. return FALSE;
  2393. if (doc_elm->Number() == position)
  2394. {
  2395. return TRUE;
  2396. }
  2397. else if (doc_elm->Number() < position)
  2398. {
  2399. while (doc_elm != NULL && doc_elm->Number() < position && doc_elm->Doc() == frames_doc)
  2400. doc_elm = doc_elm->Suc();
  2401. if (doc_elm != NULL && doc_elm->Number() > position)
  2402. //jumped too far away due to numbering gaps
  2403. doc_elm = doc_elm->Pred();
  2404. }
  2405. else //(doc_elm->Number() > position)
  2406. {
  2407. while (doc_elm != NULL && doc_elm->Number() > position && doc_elm->Doc() == frames_doc)
  2408. doc_elm = doc_elm->Pred();
  2409. }
  2410. return doc_elm != NULL && doc_elm->Doc() == frames_doc;
  2411. }
  2412. void DocumentManager::SetCurrentHistoryPos(int num, BOOL parent_doc_changed, BOOL is_user_initiated)
  2413. {
  2414. if (is_clearing || doc_list.Empty())
  2415. return;
  2416. activity_loading.Begin();
  2417. activity_refresh.Cancel();
  2418. #ifdef _PRINT_SUPPORT_
  2419. BOOL was_in_print_preview = FALSE;
  2420. if (print_preview_vd)
  2421. {
  2422. window->TogglePrintMode(TRUE);
  2423. was_in_print_preview = TRUE;
  2424. }
  2425. #endif // _PRINT_SUPPORT_
  2426. // Store document position
  2427. if (current_doc_elm)
  2428. {
  2429. StoreViewport(current_doc_elm);
  2430. }
  2431. DocListElm* prev_doc_elm = current_doc_elm;
  2432. history_walk = (current_doc_elm && current_doc_elm->Number() > num) ? DM_HIST_BACK : DM_HIST_FORW;
  2433. current_doc_elm = LastDocListElm();
  2434. while (current_doc_elm->Number() > num && current_doc_elm->Pred())
  2435. current_doc_elm = current_doc_elm->Pred();
  2436. // Check that current_doc_elm changed, to avoid sending OnNewPage
  2437. // for top document when walking in (i)frames history.
  2438. if (current_doc_elm != prev_doc_elm)
  2439. {
  2440. /** If navigate within the same document, use
  2441. * VIEWPORT_CHANGE_REASON_JUMP_TO_RELATIVE_POS */
  2442. OpViewportChangeReason reason =
  2443. (prev_doc_elm && current_doc_elm->doc == prev_doc_elm->doc ?
  2444. VIEWPORT_CHANGE_REASON_JUMP_TO_RELATIVE_POS :
  2445. VIEWPORT_CHANGE_REASON_NEW_PAGE);
  2446. if (SignalOnNewPage(reason))
  2447. waiting_for_document_ready = TRUE;
  2448. }
  2449. FlushHTTPSFromHistory(prev_doc_elm, current_doc_elm);
  2450. FramesDocument *doc = current_doc_elm->Doc();
  2451. URL url = current_doc_elm->GetUrl();
  2452. // Need to keep a pointer to these fragments before changing the URL
  2453. const uni_char *doc_fragment = doc->GetURL().UniRelName();
  2454. const uni_char *hist_fragment = url.UniRelName();
  2455. // We always have to activate the document if current_doc_elm points to another document,
  2456. // or a document that is not yet activated
  2457. BOOL activate_document = !prev_doc_elm || current_doc_elm->Doc() != prev_doc_elm->Doc() || !doc->IsCurrentDoc() || !doc->GetLogicalDocument() && load_stat == NOT_LOADING;
  2458. #ifdef _WML_SUPPORT_
  2459. if (!activate_document && current_doc_elm != prev_doc_elm &&
  2460. (current_doc_elm->GetWmlContext() || prev_doc_elm->GetWmlContext()))
  2461. activate_document = TRUE;
  2462. #endif // _WML_SUPPORT_
  2463. if (!activate_document && parent_doc_changed)
  2464. {
  2465. BOOL reload_https = current_doc_elm->GetUrl().Type() == URL_HTTPS && g_pcnet->GetIntegerPref(PrefsCollectionNetwork::AlwaysReloadHTTPSInHistory);
  2466. activate_document = reload_https;
  2467. if (!activate_document && doc->UrlNeedReload(check_expiry))
  2468. activate_document = !doc->IsLoaded() || doc->GetURL().GetAttribute(URL::KCachePolicy_MustRevalidate);
  2469. }
  2470. if (activate_document)
  2471. {
  2472. if (!parent_doc_changed)
  2473. window->ResetSecurityStateToUnknown();
  2474. ES_Runtime *es_runtime = doc->GetESRuntime();
  2475. if (es_runtime && es_runtime->Enabled())
  2476. {
  2477. ES_ThreadScheduler *es_scheduler = doc->GetESScheduler();
  2478. es_scheduler->RemoveThreads(TRUE);
  2479. }
  2480. SetCurrentNew(prev_doc_elm, is_user_initiated);
  2481. es_runtime = doc->GetESRuntime();
  2482. if (es_runtime && es_runtime->Enabled())
  2483. {
  2484. ES_ThreadScheduler *es_scheduler = doc->GetESScheduler();
  2485. RAISE_AND_RETURN_VOID_IF_ERROR(es_scheduler->Activate());
  2486. }
  2487. /** This assert just checks that the urls in the DoclistElm
  2488. * and FramesDocument are the same, although they might have
  2489. * different fragments.
  2490. */
  2491. OP_ASSERT(doc->GetURL() == url);
  2492. doc->SetUrl(url);
  2493. }
  2494. else
  2495. {
  2496. doc->SetUrl(url);
  2497. if (!GetParentDoc())
  2498. {
  2499. WindowCommander *wc = GetWindow()->GetWindowCommander();
  2500. uni_char *tempname = Window::ComposeLinkInformation(url.GetAttribute(URL::KUniName_Username_Password_Hidden).CStr(), url.GetAttribute(URL::KUniFragment_Name).CStr());
  2501. if (tempname)
  2502. {
  2503. wc->GetLoadingListener()->OnUrlChanged(wc, tempname);
  2504. OP_DELETEA(tempname);
  2505. }
  2506. }
  2507. history_walk = DM_NOT_HIST;
  2508. }
  2509. #ifdef SVG_SUPPORT
  2510. if (current_url == url && (url.RelName() || current_url.RelName()))
  2511. {
  2512. if (LogicalDocument* logdoc = doc->GetLogicalDocument())
  2513. if (HTML_Element* root = logdoc->GetDocRoot())
  2514. if (SVGImage* svg = g_svg_manager->GetSVGImage(logdoc, root))
  2515. svg->SetURLRelativePart(url.UniRelName());
  2516. }
  2517. #endif // SVG_SUPPORT
  2518. current_url = url;
  2519. referrer_url = current_doc_elm->GetReferrerUrl();
  2520. doc->SetCurrentHistoryPos(num, !prev_doc_elm || current_doc_elm->Doc() != prev_doc_elm->Doc(), is_user_initiated);
  2521. #ifdef _PRINT_SUPPORT_
  2522. if (was_in_print_preview)
  2523. window->TogglePrintMode(TRUE);
  2524. #endif // _PRINT_SUPPORT_
  2525. doc->RecalculateDeviceMediaQueries();
  2526. // Restore document position
  2527. pending_viewport_restore = FALSE;
  2528. RestoreViewport(FALSE, FALSE, doc->IsLocalDocFinished());
  2529. // Restore the :target pseudo selector, but without scrolling the document.
  2530. HTML_Document *html_doc = doc->GetHtmlDocument();
  2531. if (html_doc)
  2532. {
  2533. if (url.GetAttribute(URL::KUniFragment_Name).CStr())
  2534. {
  2535. OpString decoded_fragment;
  2536. OpString original_fragment;
  2537. if (OpStatus::IsSuccess(GetURLFragment(url, decoded_fragment, original_fragment)) &&
  2538. decoded_fragment.CStr())
  2539. {
  2540. doc->SetRelativePos(decoded_fragment.CStr(), original_fragment.CStr(), FALSE);
  2541. }
  2542. }
  2543. else if (html_doc->GetURLTargetElement())
  2544. html_doc->ApplyTargetPseudoClass(NULL);
  2545. }
  2546. if (prev_doc_elm != current_doc_elm) // Send the event only when the position really changed
  2547. {
  2548. if (doc->IsParsed()
  2549. #ifdef DELAYED_SCRIPT_EXECUTION
  2550. && !doc->GetHLDocProfile()->ESIsExecutingDelayedScript()
  2551. #endif // DELAYED_SCRIPT_EXECUTION
  2552. ) // Otherwise HandleLogdocParsingComplete() will take care of the event
  2553. RAISE_IF_MEMORY_ERROR(doc->HandleWindowEvent(ONPOPSTATE, NULL, NULL, 0, NULL));
  2554. else
  2555. doc->SendOnPopStateWhenReady();
  2556. }
  2557. CheckOnNewPageReady();
  2558. RAISE_AND_RETURN_VOID_IF_ERROR(doc->HandleHashChangeEvent(doc_fragment, hist_fragment));
  2559. OP_ASSERT(GetCurrentDoc()->IsCurrentDoc());
  2560. }
  2561. OP_STATUS DocumentManager::SetHistoryUserData(int history_ID, OpHistoryUserData* user_data)
  2562. {
  2563. OP_ASSERT(!GetParentDoc());
  2564. if (history_ID != HistoryIdNotSet)
  2565. {
  2566. DocListElm* dle = FirstDocListElm();
  2567. while (dle)
  2568. {
  2569. if (dle->GetID() == history_ID)
  2570. {
  2571. dle->SetUserData(user_data);
  2572. return OpStatus::OK;
  2573. }
  2574. dle = dle->Suc();
  2575. }
  2576. }
  2577. return OpStatus::ERR;
  2578. }
  2579. OP_STATUS DocumentManager::GetHistoryUserData(int history_ID, OpHistoryUserData** user_data) const
  2580. {
  2581. OP_ASSERT(!GetParentDoc());
  2582. if (user_data == NULL)
  2583. {
  2584. return OpStatus::ERR;
  2585. }
  2586. if (history_ID != HistoryIdNotSet)
  2587. {
  2588. DocListElm* dle = FirstDocListElm();
  2589. while (dle)
  2590. {
  2591. if (dle->GetID() == history_ID)
  2592. {
  2593. *user_data = dle->GetUserData();
  2594. return OpStatus::OK;
  2595. }
  2596. dle = dle->Suc();
  2597. }
  2598. }
  2599. return OpStatus::ERR;
  2600. }
  2601. void DocumentManager::UnloadCurrentDoc()
  2602. {
  2603. if (is_clearing || doc_list.Empty())
  2604. return;
  2605. #ifdef _PRINT_SUPPORT_
  2606. if (print_preview_vd)
  2607. window->TogglePrintMode(TRUE);
  2608. #endif // _PRINT_SUPPORT_
  2609. // Store document position
  2610. if (current_doc_elm)
  2611. {
  2612. StoreViewport(current_doc_elm);
  2613. }
  2614. DocListElm* prev_doc_elm = current_doc_elm;
  2615. current_doc_elm = NULL;
  2616. BOOL raise_OOM_condition = FALSE;
  2617. current_url.StopLoading(mh);
  2618. if (prev_doc_elm)
  2619. {
  2620. if (FramesDocument* prev_doc = prev_doc_elm->Doc())
  2621. {
  2622. URL prev_doc_url = prev_doc->GetURL();
  2623. prev_doc->SetUnloading(TRUE);
  2624. if (current_url == prev_doc_url)
  2625. if (prev_doc->StopLoading(FALSE) == OpStatus::ERR_NO_MEMORY)
  2626. raise_OOM_condition = TRUE;
  2627. if (prev_doc->Undisplay() == OpStatus::ERR_NO_MEMORY) // always call Undisplay before SetAsCurrentDoc !!!
  2628. raise_OOM_condition = TRUE;
  2629. if (prev_doc->SetAsCurrentDoc(FALSE) == OpStatus::ERR_NO_MEMORY)
  2630. raise_OOM_condition = TRUE;
  2631. prev_doc->SetUnloading(FALSE);
  2632. if (window->GetOOMOccurred())
  2633. g_memory_manager->FreeDocMemory(ULONG_MAX, TRUE);
  2634. else
  2635. g_memory_manager->CheckDocMemorySize();
  2636. }
  2637. }
  2638. SetCurrentURL(URL(), FALSE);
  2639. if (!GetFrame())
  2640. {
  2641. WindowCommander* wc = window->GetWindowCommander();
  2642. wc->GetLoadingListener()->OnUrlChanged(wc, UNI_L(""));
  2643. window->SetState(CLICKABLE);
  2644. window->DocManager()->UpdateSecurityState(FALSE);
  2645. OpString empty;
  2646. if (OpStatus::IsMemoryError(window->SetWindowTitle(empty, FALSE, FALSE)))
  2647. raise_OOM_condition = TRUE;
  2648. #ifdef SHORTCUT_ICON_SUPPORT
  2649. if (OpStatus::IsMemoryError(window->SetWindowIcon(NULL)))
  2650. raise_OOM_condition = TRUE;
  2651. #endif // SHORTCUT_ICON_SUPPORT
  2652. }
  2653. GetVisualDevice()->UpdateAll();
  2654. history_walk = DM_NOT_HIST;
  2655. if (raise_OOM_condition && !window->GetOOMOccurred())
  2656. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  2657. }
  2658. void DocumentManager::FlushHTTPSFromHistory(DocListElm* &prev_doc_elm, DocListElm* current_doc_elm)
  2659. {
  2660. BOOL pref_cache_https_after_sessions = g_pcnet->GetIntegerPref(PrefsCollectionNetwork::CacheHTTPSAfterSessions);
  2661. if (!pref_cache_https_after_sessions && prev_doc_elm && current_doc_elm && current_doc_elm != prev_doc_elm)
  2662. {
  2663. const URL prev_url = prev_doc_elm->GetUrl();
  2664. const URL curr_url = current_doc_elm->GetUrl();
  2665. if ((curr_url.Type() != URL_HTTPS && prev_url.Type() == URL_HTTPS) ||
  2666. (curr_url.Type() == URL_HTTPS && prev_url.Type() == URL_HTTPS &&
  2667. // NOTE: No servername is considered false
  2668. !curr_url.SameServer(prev_url)))
  2669. {
  2670. DocListElm *tmp_doc_elm = LastDocListElm();
  2671. while (tmp_doc_elm)
  2672. {
  2673. const URL tmp_url = tmp_doc_elm->GetUrl();
  2674. // Free all entries in history from that server that are HTTPS
  2675. if (tmp_url.Type() == URL_HTTPS &&
  2676. #ifdef APPLICATION_CACHE_SUPPORT
  2677. // Application cache urls are never removed from cache, thus the CacheHTTPSAfterSessions pref
  2678. // and application cache is in conflict. We let application cache win.
  2679. !tmp_url.GetAttribute(URL::KIsApplicationCacheURL) &&
  2680. #endif // APPLICATION_CACHE_SUPPORT
  2681. !curr_url.SameServer(tmp_url))
  2682. {
  2683. DocListElm *tmp_tmp_doc_elm = tmp_doc_elm;
  2684. tmp_doc_elm = tmp_doc_elm->Pred();
  2685. if (tmp_tmp_doc_elm != current_doc_elm)
  2686. {
  2687. RemoveElementFromHistory(tmp_tmp_doc_elm, FALSE, FALSE);
  2688. prev_doc_elm = NULL;
  2689. }
  2690. }
  2691. else
  2692. tmp_doc_elm = tmp_doc_elm->Pred();
  2693. }
  2694. }
  2695. }
  2696. }
  2697. FramesDocument* DocumentManager::GetHistoryNext() const
  2698. {
  2699. if (current_doc_elm->Suc())
  2700. return current_doc_elm->Suc()->Doc();
  2701. else
  2702. return NULL;
  2703. }
  2704. FramesDocument* DocumentManager::GetHistoryPrev() const
  2705. {
  2706. if (current_doc_elm->Pred())
  2707. return current_doc_elm->Pred()->Doc();
  2708. else
  2709. return NULL;
  2710. }
  2711. FramesDocument* DocumentManager::GetCurrentDoc() const
  2712. {
  2713. if (current_doc_elm)
  2714. return current_doc_elm->Doc();
  2715. else
  2716. return NULL;
  2717. }
  2718. FramesDocument* DocumentManager::GetCurrentVisibleDoc() const
  2719. {
  2720. #ifdef _PRINT_SUPPORT_
  2721. if (window->GetPreviewMode())
  2722. return GetPrintDoc();
  2723. else
  2724. #endif
  2725. return GetCurrentDoc();
  2726. }
  2727. #ifdef CLIENTSIDE_STORAGE_SUPPORT
  2728. OpStorageManager* DocumentManager::GetStorageManager(BOOL create)
  2729. {
  2730. if (parent_doc)
  2731. {
  2732. OP_ASSERT(!"Should use top most storage manager");
  2733. return NULL;
  2734. }
  2735. else if (!m_storage_manager && create)
  2736. m_storage_manager = OpStorageManager::Create();
  2737. return m_storage_manager;
  2738. }
  2739. void DocumentManager::SetStorageManager(OpStorageManager* new_mgr)
  2740. {
  2741. if (parent_doc)
  2742. OP_ASSERT(!"Should use top most DocumentManager");
  2743. if (new_mgr == NULL)
  2744. return;
  2745. //this method must be called when creating the window and doc manager
  2746. //so the data is shared between both windows, and not after the
  2747. //window got its own storage manger
  2748. OP_ASSERT(m_storage_manager == NULL);
  2749. m_storage_manager = new_mgr;
  2750. new_mgr->IncRefCount();
  2751. }
  2752. #endif // CLIENTSIDE_STORAGE_SUPPORT
  2753. void DocumentManager::StoreViewport(DocListElm* doc_elm)
  2754. {
  2755. OP_ASSERT(doc_elm);
  2756. FramesDocument* frm_doc = doc_elm->Doc();
  2757. doc_elm->SetLastScale(window->GetScale());
  2758. doc_elm->SetLastLayoutMode(frm_doc->GetLayoutMode());
  2759. #ifdef PAGED_MEDIA_SUPPORT
  2760. int current_page_number = -1;
  2761. if (LayoutWorkplace* workplace = frm_doc->GetLayoutWorkplace())
  2762. {
  2763. current_page_number = workplace->GetCurrentPageNumber();
  2764. doc_elm->SetCurrentPage(current_page_number);
  2765. doc_elm->ClearVisualViewport();
  2766. }
  2767. if (current_page_number == -1)
  2768. #endif // PAGED_MEDIA_SUPPORT
  2769. {
  2770. doc_elm->SetVisualViewport(frm_doc->GetVisualViewport());
  2771. for (DocumentTreeIterator it(this); it.Next();)
  2772. if (DocListElm* child_doc_elm = it.GetDocumentManager()->CurrentDocListElm())
  2773. if (FramesDocument* child_doc = child_doc_elm->Doc())
  2774. child_doc_elm->SetVisualViewport(child_doc->GetVisualViewport());
  2775. }
  2776. }
  2777. void DocumentManager::RestoreViewport(BOOL only_pending_restoration, BOOL recurse, BOOL make_fit)
  2778. {
  2779. if (!current_doc_elm)
  2780. return;
  2781. FramesDocument* frm_doc = current_doc_elm->Doc();
  2782. if (frm_doc->GetLayoutMode() != current_doc_elm->GetLastLayoutMode())
  2783. current_doc_elm->ClearVisualViewport();
  2784. int negative_overflow = frm_doc->NegativeOverflow();
  2785. OpRect doc_rect(-negative_overflow, 0, negative_overflow + frm_doc->Width(), frm_doc->Height());
  2786. BOOL restoration_failed = FALSE;
  2787. #ifdef PAGED_MEDIA_SUPPORT
  2788. int page_number = current_doc_elm->GetCurrentPage();
  2789. if (page_number != -1)
  2790. {
  2791. OP_ASSERT(!current_doc_elm->HasVisualViewport());
  2792. restoration_failed = TRUE;
  2793. if (!only_pending_restoration || pending_viewport_restore)
  2794. if (LayoutWorkplace* workplace = frm_doc->GetLayoutWorkplace())
  2795. if (workplace->SetCurrentPageNumber(page_number, VIEWPORT_CHANGE_REASON_HISTORY_NAVIGATION) || make_fit)
  2796. if (make_fit || workplace->GetCurrentPageNumber() == page_number)
  2797. {
  2798. /* Page was successfully restored. Now clear the stored page number (and
  2799. stored visual viewport, if set), so that future reflows won't bump us to
  2800. a stored page. That would be kind of annoying for the user if she has
  2801. moved to a different page in the meantime. */
  2802. current_doc_elm->SetCurrentPage(-1);
  2803. restoration_failed = FALSE;
  2804. }
  2805. }
  2806. else
  2807. #endif // PAGED_MEDIA_SUPPORT
  2808. {
  2809. // Attempt to restore visual viewport
  2810. if (current_doc_elm->HasVisualViewport())
  2811. {
  2812. OpRect viewport = current_doc_elm->GetVisualViewport();
  2813. BOOL has_size = viewport.width > 0 && viewport.height > 0;
  2814. BOOL fits = has_size ? doc_rect.Contains(viewport) : doc_rect.Contains(OpPoint(viewport.x, viewport.y));
  2815. if (make_fit && !fits)
  2816. {
  2817. // Doesn't fit. Try to make it fit. Will fail if the viewport is larger than the document.
  2818. if (viewport.x > doc_rect.x + doc_rect.width - viewport.width)
  2819. viewport.x = doc_rect.x + doc_rect.width - viewport.width;
  2820. if (viewport.y > doc_rect.y + doc_rect.height - viewport.height)
  2821. viewport.y = doc_rect.y + doc_rect.height - viewport.height;
  2822. if (viewport.x < doc_rect.x)
  2823. viewport.x = doc_rect.x;
  2824. if (viewport.y < doc_rect.y)
  2825. viewport.y = doc_rect.y;
  2826. }
  2827. if (make_fit || fits)
  2828. {
  2829. if (!only_pending_restoration || pending_viewport_restore)
  2830. {
  2831. if (has_size)
  2832. frm_doc->RequestSetVisualViewport(viewport, VIEWPORT_CHANGE_REASON_HISTORY_NAVIGATION);
  2833. else
  2834. frm_doc->RequestSetVisualViewPos(viewport.x, viewport.y, VIEWPORT_CHANGE_REASON_HISTORY_NAVIGATION);
  2835. current_doc_elm->ClearVisualViewport();
  2836. }
  2837. }
  2838. else
  2839. restoration_failed = TRUE;
  2840. }
  2841. if (recurse)
  2842. // Restore child frames and iframes
  2843. for (DocumentTreeIterator it(this); it.Next();)
  2844. it.GetDocumentManager()->RestoreViewport(only_pending_restoration, FALSE, make_fit);
  2845. }
  2846. pending_viewport_restore = restoration_failed;
  2847. }
  2848. OP_STATUS DocumentManager::AddNewHistoryPosition(URL& url, const DocumentReferrer& ref_url, int history_num, const uni_char* doc_title, BOOL make_current /* = FALSE */, BOOL is_plugin /* = FALSE */, FramesDocument* use_existing_doc /* = NULL */, int scale /* = 100 */)
  2849. {
  2850. URLStatus url_stat = url.Status(TRUE);
  2851. if (url_stat == URL_EMPTY || url.IsEmpty()) // We are not going to add a doc with an empty URL. Return quietly
  2852. return OpStatus::OK;
  2853. FramesDocument *doc;
  2854. if (use_existing_doc)
  2855. doc = use_existing_doc;
  2856. else
  2857. {
  2858. DocumentOrigin* origin = DocumentOrigin::Make(url);
  2859. if (!origin)
  2860. return OpStatus::ERR_NO_MEMORY;
  2861. doc = OP_NEW(FramesDocument, (this, url, origin, GetSubWinId(), is_plugin));
  2862. origin->DecRef();
  2863. origin = NULL;
  2864. }
  2865. if (doc)
  2866. {
  2867. BOOL replaced_empty = FALSE;
  2868. history_num = history_num != -1 ? history_num : GetNextHistoryNumber(replace, replaced_empty);
  2869. DocListElm* new_dle = OP_NEW(DocListElm, (url, doc, use_existing_doc != doc, history_num, GetNextDocListElmId()));
  2870. if (new_dle)
  2871. {
  2872. if (make_current)
  2873. current_doc_elm = new_dle;
  2874. if (replaced_empty)
  2875. current_doc_elm->SetReplacedEmptyPosition();
  2876. if (doc == doc->GetTopDocument())
  2877. window->SetType(doc->Type());
  2878. InsertHistoryElement(new_dle);
  2879. new_dle->SetReferrerUrl(ref_url, ShouldSendReferrer());
  2880. if (doc_title && *doc_title)
  2881. RETURN_IF_MEMORY_ERROR(new_dle->SetTitle(doc_title));
  2882. #ifdef DOCHAND_HISTORY_SAVE_ZOOM_LEVEL
  2883. new_dle->SetLastScale(scale);
  2884. #endif // DOCHAND_HISTORY_SAVE_ZOOM_LEVEL
  2885. int win_history_num = window->GetCurrentHistoryNumber();
  2886. if (history_num == win_history_num && !GetWindow()->IsMailOrNewsfeedWindow())
  2887. {
  2888. #ifdef PREFS_HOSTOVERRIDE
  2889. // Bug#128887: Set the forced character encoding if a host override exists.
  2890. // Check correctness
  2891. if (g_pcdisplay->IsPreferenceOverridden(PrefsCollectionDisplay::ForceEncoding, url))
  2892. {
  2893. const OpStringC force_encoding(g_pcdisplay->GetStringPref(PrefsCollectionDisplay::ForceEncoding, url));
  2894. if (!force_encoding.IsEmpty())
  2895. {
  2896. char sbencoding[128]; /* ARRAY OK 2008-02-28 jl */
  2897. uni_cstrlcpy(sbencoding, force_encoding.CStr(), ARRAY_SIZE(sbencoding));
  2898. window->SetForceEncoding(sbencoding, TRUE);
  2899. }
  2900. }
  2901. #endif // PREFS_HOSTOVERRIDE
  2902. RETURN_IF_MEMORY_ERROR(window->UpdateTitle());
  2903. }
  2904. history_len++;
  2905. }
  2906. else
  2907. return OpStatus::ERR_NO_MEMORY;
  2908. }
  2909. else
  2910. return OpStatus::ERR_NO_MEMORY;
  2911. return OpStatus::OK;
  2912. }
  2913. void DocumentManager::SetShowImg(BOOL val)
  2914. {
  2915. #ifdef _PRINT_SUPPORT_
  2916. BOOL was_in_print_preview = FALSE;
  2917. if (print_preview_vd)
  2918. {
  2919. window->TogglePrintMode(TRUE);
  2920. was_in_print_preview = TRUE;
  2921. }
  2922. #endif // _PRINT_SUPPORT_
  2923. if (!current_doc_elm)
  2924. return;
  2925. FramesDocument* doc = current_doc_elm->Doc();
  2926. if (doc)
  2927. doc->SetMode(val, window->LoadImages(), window->GetCSSMode(), check_expiry);
  2928. #ifdef _PRINT_SUPPORT_
  2929. if (was_in_print_preview)
  2930. window->TogglePrintMode(TRUE);
  2931. #endif // _PRINT_SUPPORT_
  2932. }
  2933. OP_STATUS DocumentManager::ReformatCurrentDoc()
  2934. {
  2935. #ifdef _PRINT_SUPPORT_
  2936. BOOL was_in_print_preview = FALSE;
  2937. if (print_preview_vd)
  2938. {
  2939. window->TogglePrintMode(TRUE);
  2940. was_in_print_preview = TRUE;
  2941. }
  2942. #endif // _PRINT_SUPPORT_
  2943. if (!current_doc_elm)
  2944. return OpStatus::OK;
  2945. FramesDocument* doc = current_doc_elm->Doc();
  2946. LayoutWorkplace* wp = doc->GetLogicalDocument() ? doc->GetLogicalDocument()->GetLayoutWorkplace() : NULL;
  2947. if (doc->IsUndisplaying())
  2948. return OpStatus::OK;
  2949. if (wp)
  2950. wp->SetCanYield(TRUE);
  2951. if (OpStatus::IsMemoryError(doc->Reflow(TRUE, FALSE)))
  2952. {
  2953. if (wp)
  2954. wp->SetCanYield(FALSE);
  2955. return OpStatus::ERR_NO_MEMORY;
  2956. }
  2957. if (wp)
  2958. {
  2959. wp->SetCanYield(FALSE);
  2960. doc->GetHLDocProfile()->GetCSSCollection()->StyleChanged(CSSCollection::CHANGED_MEDIA_QUERIES);
  2961. }
  2962. #ifdef _PRINT_SUPPORT_
  2963. if (was_in_print_preview)
  2964. window->TogglePrintMode(TRUE); // rg this one doesn't work very well (if at all)
  2965. #endif // _PRINT_SUPPORT_
  2966. return OpStatus::OK;
  2967. }
  2968. OP_STATUS DocumentManager::ReformatDoc(FramesDocument* doc)
  2969. {
  2970. #ifdef _PRINT_SUPPORT_
  2971. BOOL was_in_print_preview = FALSE;
  2972. if (print_preview_vd)
  2973. {
  2974. window->TogglePrintMode(TRUE);
  2975. was_in_print_preview = TRUE;
  2976. }
  2977. #endif // _PRINT_SUPPORT_
  2978. LayoutWorkplace* wp = doc->GetLogicalDocument() ? doc->GetLogicalDocument()->GetLayoutWorkplace() : NULL;
  2979. if (wp)
  2980. wp->SetCanYield(TRUE);
  2981. HTML_Element* root = doc->GetDocRoot();
  2982. if (root)
  2983. root->MarkPropsDirty(doc);
  2984. if (wp)
  2985. wp->SetCanYield(FALSE);
  2986. #ifdef _PRINT_SUPPORT_
  2987. if (was_in_print_preview)
  2988. window->TogglePrintMode(TRUE); // rg this one doesn't work very well (if at all)
  2989. #endif // _PRINT_SUPPORT_
  2990. return OpStatus::OK;
  2991. }
  2992. DocListElm* DocumentManager::FindDocListElm(FramesDocument *doc) const
  2993. {
  2994. DocListElm *dle;
  2995. for (dle = current_doc_elm; dle; dle = (DocListElm *) dle->Suc())
  2996. if (dle->Doc() == doc)
  2997. return dle;
  2998. for (dle = current_doc_elm; dle; dle = (DocListElm *) dle->Pred())
  2999. if (dle->Doc() == doc)
  3000. return dle;
  3001. return NULL;
  3002. }
  3003. void DocumentManager::UpdateVisitedLinks(const URL& url)
  3004. {
  3005. #ifdef _PRINT_SUPPORT_
  3006. if (print_preview_vd)
  3007. return;
  3008. #endif // _PRINT_SUPPORT_
  3009. if (current_doc_elm && current_doc_elm->Doc())
  3010. {
  3011. URL current_doc_url = current_doc_elm->GetUrl();
  3012. URL doc_url = current_doc_elm->GetUrl().GetAttribute(URL::KMovedToURL, TRUE);
  3013. if (doc_url.IsEmpty())
  3014. doc_url = current_doc_url;
  3015. if (!(doc_url == url) || GetLoadStatus() == NOT_LOADING)
  3016. current_doc_elm->Doc()->UpdateLinkVisited();
  3017. }
  3018. }
  3019. void DocumentManager::CancelRefresh()
  3020. {
  3021. if (waiting_for_refresh_id)
  3022. {
  3023. mh->RemoveDelayedMessage(MSG_START_REFRESH_LOADING, static_cast<MH_PARAM_1>(waiting_for_refresh_id), GetSubWinId());
  3024. activity_refresh.Cancel();
  3025. }
  3026. waiting_for_refresh_id = 0;
  3027. }
  3028. void DocumentManager::SetRefreshDocument(URL_ID url_id, unsigned long delay)
  3029. {
  3030. if (waiting_for_refresh_id != url_id)
  3031. {
  3032. if (waiting_for_refresh_id)
  3033. mh->RemoveDelayedMessage(MSG_START_REFRESH_LOADING, static_cast<MH_PARAM_1>(waiting_for_refresh_id), GetSubWinId());
  3034. #ifdef _AUTO_WIN_RELOAD_SUPPORT_
  3035. // Fix for bug #153586 - User defined reload setting overrides page refresh
  3036. if (window->GetUserAutoReload()->GetOptIsEnabled())
  3037. {
  3038. waiting_for_refresh_id = 0;
  3039. return;
  3040. }
  3041. #endif // _AUTO_WIN_RELOAD_SUPPORT_
  3042. waiting_for_refresh_id = url_id;
  3043. waiting_for_refresh_delay = delay;
  3044. if (waiting_for_refresh_id)
  3045. {
  3046. mh->PostDelayedMessage(MSG_START_REFRESH_LOADING, static_cast<MH_PARAM_1>(url_id), GetSubWinId(), delay);
  3047. activity_refresh.Begin();
  3048. }
  3049. }
  3050. }
  3051. void DocumentManager::Refresh(URL_ID id)
  3052. {
  3053. OpAutoActivity local_activity_refresh(ACTIVITY_METAREFRESH);
  3054. if (id != waiting_for_refresh_id)
  3055. return;
  3056. waiting_for_refresh_id = 0;
  3057. #ifdef _PRINT_SUPPORT_
  3058. if (print_preview_vd)
  3059. {
  3060. pending_refresh_id = id;
  3061. return;
  3062. }
  3063. #endif // _PRINT_SUPPORT_
  3064. FramesDocument* doc = GetCurrentDoc();
  3065. if (doc)
  3066. {
  3067. URL url = doc->GetRefreshURL(id);
  3068. BOOL is_redirecting = doc->GetURL().Id(TRUE) != url.Id(TRUE);
  3069. BOOL reload = !is_redirecting && url.GetAttribute(URL::KUniFragment_Name).IsEmpty();
  3070. BOOL allow_refresh = window->GetWindowCommander()->GetDocumentListener()->OnRefreshUrl(window->GetWindowCommander(), url.GetAttribute(URL::KUniName_Username_Password_Hidden, TRUE).CStr());
  3071. if (!allow_refresh && !is_redirecting)
  3072. return;
  3073. SetUserAutoReload(FALSE);
  3074. if (is_redirecting)
  3075. SetLoadStatus(WAIT_FOR_HEADER);
  3076. if (!url.IsEmpty())
  3077. {
  3078. if(url.Type() == URL_HTTP || url.Type() == URL_HTTPS)
  3079. url.SetHTTP_Method(HTTP_METHOD_GET);
  3080. DocumentReferrer ref_url = GenerateReferrerURL();
  3081. StopLoading(FALSE);
  3082. if (reload)
  3083. {
  3084. SetReload(TRUE);
  3085. SetReloadFlags(TRUE, FALSE, TRUE, TRUE);
  3086. }
  3087. #ifdef SKIP_REFRESH_ON_BACK
  3088. else if (waiting_for_refresh_delay < SKIP_REFRESH_SECONDS * 1000)
  3089. /* The current document (the source of the redirect) should be
  3090. skipped in the history. We accomplish this by reusing its
  3091. history number for the new document. This has the side-
  3092. effect that the old document is automatically removed when
  3093. replaced, and we also avoid holes in the history (which we
  3094. might get if we just remove the old history position.) */
  3095. SetUseHistoryNumber(current_doc_elm->Number());
  3096. #endif // SKIP_REFRESH_ON_BACK
  3097. SetRedirect(is_redirecting);
  3098. OpenURL(url, ref_url, TRUE, reload);
  3099. }
  3100. }
  3101. }
  3102. OP_STATUS DocumentManager::HandleDataLoaded(URL_ID url_id)
  3103. {
  3104. OP_PROBE5(OP_PROBE_DOCUMENTMANAGER_HANDLEDATALOADED);
  3105. OP_STATUS status = OpStatus::OK;
  3106. OpStatus::Ignore(status);
  3107. if (current_url.Id(TRUE) == url_id)
  3108. use_current_doc = FALSE;
  3109. DM_LoadStat ls = GetLoadStatus();
  3110. if (ls == WAIT_FOR_HEADER || ls == WAIT_FOR_ACTION)
  3111. {
  3112. status = HandleHeaderLoaded(url_id, FALSE);
  3113. ls = GetLoadStatus();
  3114. }
  3115. FramesDocument* doc = GetCurrentDoc();
  3116. if (ls == DOC_CREATED || ls == NOT_LOADING || ls == WAIT_MULTIPART_RELOAD && url_id != current_url.Id(TRUE))
  3117. {
  3118. // dispatch to document
  3119. if (doc)
  3120. status = doc->HandleLoading(MSG_URL_DATA_LOADED, url_id, 0);
  3121. }
  3122. else if (ls != WAIT_FOR_ECMASCRIPT && current_url.Id(TRUE) == url_id && current_url.Status(TRUE) != URL_LOADING)
  3123. HandleAllLoaded(url_id);
  3124. if (current_url.Status(TRUE) != URL_LOADING && ls == NOT_LOADING && (!doc || doc->IsLoaded()))
  3125. EndProgressDisplay();
  3126. return status;
  3127. }
  3128. #ifdef WEB_HANDLERS_SUPPORT
  3129. class WebHandlerCallback : public OpDocumentListener::WebHandlerCallback
  3130. {
  3131. DocumentManager* doc_man;
  3132. URL target_url;
  3133. URL current_url;
  3134. DocumentReferrer referrer;
  3135. BOOL user_initiated;
  3136. BOOL entered_by_user;
  3137. const uni_char* description;
  3138. OpString8 protocol_or_mime_type;
  3139. BOOL show_never_ask_me_again;
  3140. BOOL content_handler;
  3141. OpString target_host;
  3142. public:
  3143. WebHandlerCallback(DocumentManager* doc_man, URL& url, DocumentReferrer& ref, URL& target_url, BOOL user_init, BOOL user_entered, const uni_char *description, BOOL show_dont_ask_me_again = TRUE, BOOL content_handler = TRUE)
  3144. : doc_man(doc_man)
  3145. , target_url(target_url)
  3146. , current_url(url)
  3147. , referrer(ref)
  3148. , user_initiated(user_init)
  3149. , entered_by_user(user_entered)
  3150. , description(description)
  3151. , show_never_ask_me_again(show_dont_ask_me_again)
  3152. , content_handler(content_handler)
  3153. {
  3154. }
  3155. virtual ~WebHandlerCallback() {}
  3156. OP_STATUS Construct(const char* protocol_or_mime_type)
  3157. {
  3158. RETURN_IF_ERROR(this->protocol_or_mime_type.Set(protocol_or_mime_type));
  3159. return target_url.GetAttribute(URL::KUniHostName, target_host);
  3160. }
  3161. virtual void OnOK(BOOL dont_ask_again, const uni_char* filename)
  3162. {
  3163. if (content_handler)
  3164. {
  3165. Viewer* viewer = g_viewers->FindViewerByMimeType(protocol_or_mime_type);
  3166. if (viewer && dont_ask_again)
  3167. {
  3168. viewer->SetFlag(ViewActionFlag::USERDEFINED_VALUE);
  3169. }
  3170. if (viewer && filename)
  3171. {
  3172. if (!*filename)
  3173. {
  3174. viewer->ResetAction(dont_ask_again);
  3175. }
  3176. else
  3177. {
  3178. viewer->SetAction(VIEWER_APPLICATION);
  3179. if (OpStatus::IsMemoryError(viewer->SetApplicationToOpenWith(filename)))
  3180. goto raise_oom_condition;
  3181. }
  3182. doc_man->OpenURL(current_url, referrer, TRUE, FALSE, user_initiated, FALSE, entered_by_user ? WasEnteredByUser : NotEnteredByUser);
  3183. }
  3184. else
  3185. {
  3186. doc_man->OpenURL(target_url, DocumentReferrer(current_url), TRUE, FALSE, user_initiated, FALSE, entered_by_user ? WasEnteredByUser : NotEnteredByUser);
  3187. }
  3188. #if defined PREFS_HAS_PREFSFILE && defined PREFS_WRITE
  3189. if (dont_ask_again)
  3190. {
  3191. TRAPD(exception, g_viewers->WriteViewersL());
  3192. if (OpStatus::IsMemoryError(exception))
  3193. goto raise_oom_condition;
  3194. }
  3195. #endif // defined PREFS_HAS_PREFSFILE && defined PREFS_WRITE
  3196. }
  3197. else
  3198. {
  3199. OpString protocol;
  3200. if (OpStatus::IsMemoryError(protocol.SetFromUTF8(current_url.GetAttribute(URL::KProtocolName).CStr())))
  3201. goto raise_oom_condition;
  3202. TrustedProtocolData data;
  3203. int index = g_pcdoc->GetTrustedProtocolInfo(protocol, data);
  3204. if (index != -1)
  3205. {
  3206. if (dont_ask_again)
  3207. {
  3208. data.user_defined = TRUE;
  3209. data.flags |= TrustedProtocolData::TP_UserDefined;
  3210. }
  3211. if (filename)
  3212. {
  3213. if (*filename)
  3214. {
  3215. data.viewer_mode = UseCustomApplication;
  3216. data.filename = filename;
  3217. data.flags |= (TrustedProtocolData::TP_Filename|TrustedProtocolData::TP_ViewerMode);
  3218. }
  3219. else
  3220. {
  3221. data.viewer_mode = UseDefaultApplication;
  3222. data.flags |= TrustedProtocolData::TP_ViewerMode;
  3223. }
  3224. }
  3225. TRAPD(exception, g_pcdoc->SetTrustedProtocolInfoL(index, data));
  3226. if (OpStatus::IsMemoryError(exception))
  3227. goto raise_oom_condition;
  3228. #if defined PREFS_HAS_PREFSFILE && defined PREFS_WRITE
  3229. if (dont_ask_again)
  3230. {
  3231. TRAP(exception, g_pcdoc->WriteTrustedProtocolsL(g_pcdoc->GetNumberOfTrustedProtocols()));
  3232. if (OpStatus::IsMemoryError(exception))
  3233. goto raise_oom_condition;
  3234. }
  3235. #endif // defined PREFS_HAS_PREFSFILE && defined PREFS_WRITE
  3236. }
  3237. if (filename)
  3238. {
  3239. doc_man->OpenURL(current_url, referrer, TRUE, FALSE, user_initiated, FALSE, entered_by_user ? WasEnteredByUser : NotEnteredByUser);
  3240. }
  3241. else
  3242. {
  3243. doc_man->OpenURL(target_url, referrer, TRUE, FALSE, user_initiated, FALSE, entered_by_user ? WasEnteredByUser : NotEnteredByUser);
  3244. }
  3245. }
  3246. OP_DELETE(this);
  3247. return;
  3248. raise_oom_condition:
  3249. doc_man->RaiseCondition(OpStatus::ERR_NO_MEMORY);
  3250. OP_DELETE(this);
  3251. return;
  3252. }
  3253. virtual void OnCancel()
  3254. {
  3255. OP_DELETE(this);
  3256. }
  3257. virtual const uni_char* GetDescription() const { return description; }
  3258. virtual const char* GetMimeTypeOrProtocol() const { return protocol_or_mime_type; }
  3259. const uni_char* GetTargetHostName() const { return target_host.CStr(); }
  3260. virtual BOOL ShowNeverAskMeAgain() const { return show_never_ask_me_again; }
  3261. virtual BOOL IsProtocolHandler() const { return !content_handler; }
  3262. };
  3263. #endif // WEB_HANDLERS_SUPPORT
  3264. OP_STATUS DocumentManager::HandleHeaderLoaded(URL_ID url_id, BOOL check_if_inline_expired)
  3265. {
  3266. BOOL pref_suppress_external_embeds = g_pcdoc->GetIntegerPref(PrefsCollectionDoc::SuppressExternalEmbeds);
  3267. if (current_url.IsEmpty() || current_url.Id(TRUE) != url_id || GetLoadStatus() == NOT_LOADING)
  3268. {
  3269. // check frames
  3270. if (FramesDocument* doc = GetCurrentDoc())
  3271. return doc->HandleLoading(MSG_HEADER_LOADED, url_id, check_if_inline_expired);
  3272. return OpStatus::OK;
  3273. }
  3274. if (GetLoadStatus() == WAIT_FOR_HEADER || GetLoadStatus() == WAIT_FOR_ACTION)
  3275. {
  3276. BOOL update_this_window = TRUE;
  3277. URL moved_url = current_url.GetAttribute(URL::KMovedToURL, TRUE);
  3278. if (!moved_url.IsEmpty() && !(moved_url == current_url))
  3279. {
  3280. if ((current_url.Type() == URL_HTTPS || moved_url.Type() == URL_HTTPS) // only redirects to/from HTTPS
  3281. && user_started_loading // only if the user started the loading
  3282. && GetParentDoc() == NULL) // only for the top document
  3283. {
  3284. window->ResetSecurityStateToUnknown();
  3285. }
  3286. #ifdef HISTORY_SUPPORT
  3287. OP_STATUS ostat = GetWindow()->AddToGlobalHistory(current_url,
  3288. current_url.GetAttribute(URL::KUniName).CStr());
  3289. if(OpStatus::IsFatal(ostat))
  3290. return ostat;
  3291. #endif // HISTORY_SUPPORT
  3292. GetWindow()->ClearMovedUrls();
  3293. if (current_url.UniRelName())
  3294. // If a URL we were redirected to has a relative part - use it.
  3295. SetCurrentURL(URL(moved_url, ((moved_url.UniRelName()) ? moved_url.UniRelName() : current_url.UniRelName())), TRUE);
  3296. else
  3297. SetCurrentURL(moved_url, TRUE);
  3298. }
  3299. window->SetState(CLICKABLE);
  3300. if (!window->GetPrivacyMode())
  3301. current_url.Access(TRUE);
  3302. const uni_char* app = NULL;
  3303. RETURN_IF_MEMORY_ERROR(UpdateAction(app));
  3304. ViewAction action = GetAction();
  3305. if (action == VIEWER_WAIT_FOR_DATA)
  3306. {
  3307. SetAction(VIEWER_NOT_DEFINED);
  3308. SetLoadStat(WAIT_FOR_ACTION);
  3309. return OpStatus::OK;
  3310. }
  3311. #ifdef WEB_HANDLERS_SUPPORT
  3312. BOOL force_ask_user = FALSE;
  3313. if (action == VIEWER_WEB_APPLICATION)
  3314. {
  3315. BOOL allowed = TRUE;
  3316. if (current_url.Type() == URL_HTTPS)
  3317. {
  3318. URL target_url;
  3319. if (app && *app)
  3320. target_url = g_url_api->GetURL(current_url, app);
  3321. OpStatus::Ignore(OpSecurityManager::CheckSecurity(OpSecurityManager::DOM_STANDARD,
  3322. OpSecurityContext(current_url),
  3323. OpSecurityContext(target_url),
  3324. allowed));
  3325. }
  3326. // Check against cascades/loops.
  3327. Viewer* viewer;
  3328. RETURN_IF_MEMORY_ERROR(g_viewers->FindViewerByWebApplication(current_url.GetAttribute(URL::KUniName_With_Fragment_Username_Password_Escaped_NOT_FOR_UI).CStr(), viewer));
  3329. if (!allowed || viewer || current_url.GetAttribute(URL::KHTTP_Method) != HTTP_METHOD_GET)
  3330. {
  3331. RETURN_IF_MEMORY_ERROR(g_viewers->FindViewerByURL(current_url, viewer, TRUE));
  3332. OP_ASSERT(viewer);
  3333. SetAction(Viewers::GetDefaultAction(viewer->GetContentTypeString8()));
  3334. SetActionLocked(TRUE);
  3335. action = GetAction();
  3336. }
  3337. else
  3338. {
  3339. OpSocketAddressNetType net_type = NETTYPE_UNDETERMINED;
  3340. if (current_url.Status(TRUE) == URL_LOADED)
  3341. net_type = static_cast<OpSocketAddressNetType>(current_url.GetAttribute(URL::KLoadedFromNetType));
  3342. else
  3343. {
  3344. ServerName* server_name = current_url.GetServerName();
  3345. if (server_name)
  3346. net_type = server_name->GetNetType();
  3347. }
  3348. force_ask_user = (net_type == NETTYPE_LOCALHOST || net_type == NETTYPE_PRIVATE || net_type == NETTYPE_UNDETERMINED);
  3349. }
  3350. }
  3351. #endif // WEB_HANDLERS_SUPPORT
  3352. BOOL out_of_memory;
  3353. OP_STATUS stat = OpStatus::OK;
  3354. OpStatus::Ignore(stat);
  3355. // suppress the showing of mail and news content that does not use Opera as viewer (stighal, 2002-04-26)
  3356. if (pref_suppress_external_embeds
  3357. && (action != VIEWER_OPERA && action != VIEWER_SAVE)
  3358. && window->IsSuppressWindow())
  3359. {
  3360. use_current_doc = FALSE;
  3361. return OpStatus::OK;
  3362. }
  3363. if (load_image_only || save_image_only)
  3364. if (!current_url.IsImage())
  3365. {
  3366. StopLoading(FALSE);
  3367. return OpStatus::OK;
  3368. }
  3369. if (save_image_only)
  3370. action = VIEWER_SAVE;
  3371. #ifdef MEDIA_HTML_SUPPORT
  3372. // suppress displaying audio/video if the media backend does not support it;
  3373. // user will have to select action.
  3374. if (current_url.ContentType() == URL_MEDIA_CONTENT && action == VIEWER_OPERA)
  3375. {
  3376. if (!g_media_module.IsMediaPlayableUrl(current_url))
  3377. action = VIEWER_ASK_USER;
  3378. }
  3379. #endif
  3380. switch (action)
  3381. {
  3382. #ifndef NO_SAVE_SUPPORT
  3383. case VIEWER_SAVE:
  3384. {
  3385. const OpStringC8 mime_type = current_url.GetAttribute(URL::KMIME_Type, TRUE);
  3386. Viewer* viewer = g_viewers->FindViewerByMimeType(mime_type);
  3387. SetLoadStat(WAIT_FOR_USER);
  3388. #ifndef WIC_USE_DOWNLOAD_CALLBACK
  3389. OpString url_name, suggested_filename;
  3390. current_url.GetAttribute(URL::KUniName_Username_Password_Hidden, url_name, TRUE);
  3391. if (OpStatus::IsError(current_url.GetAttribute(URL::KSuggestedFileName_L, suggested_filename, TRUE)) ||
  3392. url_name.IsEmpty() ||
  3393. suggested_filename.IsEmpty())
  3394. {
  3395. return OpStatus::ERR_NO_MEMORY;
  3396. }
  3397. #endif // WIC_USE_DOWNLOAD_CALLBACK
  3398. if(viewer)
  3399. {
  3400. # if defined (SDK)
  3401. # ifdef GTK_DOWNLOAD_EXTENSION
  3402. ServerName* sname = current_url.GetServerName();
  3403. unsigned short port = current_url.GetServerPort();
  3404. AuthElm* auth = sname->Get_Auth(NULL, (port == 0) ? 80 : port, current_url.GetPath(), current_url.Type(), 0);
  3405. char *auth_credentials = NULL;
  3406. if (auth)
  3407. OP_STATUS status = auth->GetAuthString(&auth_credentials, current_url.GetRep());
  3408. const uni_char* suggested_filename = (viewer->GetFlags() & VIEWER_FLAG_SAVE_DIRECTLY) ? viewer->GetSaveToFolder() : NULL;
  3409. GtkWidget* ow = GTK_WIDGET(((GdkOpWindow*)GetWindow()->GetOpWindow())->GetGtkWidget());
  3410. OP_ASSERT(ow);
  3411. if (ow)
  3412. {
  3413. gchar* suggested_filename_utf8;
  3414. if (suggested_filename)
  3415. suggested_filename_utf8 = g_utf16_to_utf8(suggested_filename, -1, NULL, NULL, NULL);
  3416. else
  3417. suggested_filename_utf8 = g_strdup("");
  3418. GtkOperaDownloadExtension* download_extension = GTK_OPERA_DOWNLOAD_EXTENSION(gtk_operawidget_get_extension( GTK_OPERA_WIDGET(ow), GTK_OPERA_DOWNLOAD_EXTENSION_TYPE ));
  3419. if (suggested_filename_utf8)
  3420. {
  3421. if (download_extension)
  3422. g_signal_emit(G_OBJECT(download_extension), gtk_opera_download_extension_signals[GTK_OPERA_DOWNLOAD_EXTENSION_REQUEST], 0,
  3423. current_url.Name(),
  3424. suggested_filename_utf8,
  3425. current_url.GetAttribute(URL::KMIME_Type),
  3426. auth_credentials,
  3427. 0,
  3428. (viewer->GetFlags() & VIEWER_FLAG_SAVE_DIRECTLY) ? OpDocumentListener::SAVE : OpDocumentListener::ASK_USER);
  3429. g_free(suggested_filename_utf8);
  3430. }
  3431. else
  3432. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  3433. }
  3434. OP_DELETEA(auth_credentials);
  3435. # else // GTK_DOWNLOAD_EXTENSION
  3436. window->GetWindowCommander()->GetDocumentListener()->OnDownloadRequest(
  3437. window->GetWindowCommander(),
  3438. current_url.GetUniName(TRUE, PASSWORD_HIDDEN),
  3439. (viewer->GetFlags() & VIEWER_FLAG_SAVE_DIRECTLY) ? viewer->GetSaveToFolder() : NULL,
  3440. current_url.GetAttribute(URL::KMIME_Type),
  3441. 0,
  3442. (viewer->GetFlags() & VIEWER_FLAG_SAVE_DIRECTLY) ? OpDocumentListener::SAVE : OpDocumentListener::ASK_USER);
  3443. # endif // GTK_DOWNLOAD_EXTENSION
  3444. # else // SDK
  3445. # if defined (WIC_USE_DOWNLOAD_CALLBACK)
  3446. TransferManagerDownloadCallback * t_tmdc = OP_NEW(TransferManagerDownloadCallback, (this, current_url, viewer, current_action_flag));
  3447. if (!t_tmdc)
  3448. return OpStatus::ERR_NO_MEMORY;
  3449. WindowCommander * wc = window->GetWindowCommander();
  3450. wc->GetDocumentListener()->OnDownloadRequest(wc, t_tmdc);
  3451. OP_BOOLEAN finished = t_tmdc->Execute();
  3452. current_action_flag.Unset(ViewActionFlag::SAVE_AS);
  3453. if(finished == OpBoolean::IS_FALSE)
  3454. SetLoadStat(WAIT_FOR_USER);
  3455. else
  3456. return finished;
  3457. break;
  3458. # else // !WIC_USE_DOWNLOAD_CALLBACK
  3459. BOOL can_do = FALSE;
  3460. if (!current_action_flag.IsSet(ViewActionFlag::SAVE_AS)
  3461. && viewer->GetFlags().IsSet(ViewActionFlag::SAVE_DIRECTLY))
  3462. OpStatus::Ignore(SetSaveDirect(viewer, can_do));
  3463. if (!can_do)
  3464. {
  3465. current_action_flag.Unset(ViewActionFlag::SAVE_AS);
  3466. window->GetWindowCommander()->GetDocumentListener()->OnDownloadRequest(
  3467. window->GetWindowCommander(),
  3468. url_name.CStr(),
  3469. suggested_filename.CStr(),
  3470. current_url.GetAttribute(URL::KMIME_Type, TRUE).CStr(),
  3471. current_url.GetContentSize(),
  3472. (viewer->GetFlags().IsSet(ViewActionFlag::SAVE_DIRECTLY)) ? OpDocumentListener::SAVE : OpDocumentListener::ASK_USER,
  3473. (viewer->GetFlags().IsSet(ViewActionFlag::SAVE_DIRECTLY)) ? viewer->GetSaveToFolder() : NULL);
  3474. }
  3475. else
  3476. {
  3477. current_action_flag.Set(ViewActionFlag::SAVE_DIRECTLY);
  3478. SetLoadStatus(WAIT_FOR_LOADING_FINISHED);
  3479. if (current_url.Status(TRUE) != URL_LOADING)
  3480. HandleAllLoaded(url_id);
  3481. break;
  3482. }
  3483. # endif // !WIC_USE_DOWNLOAD_CALLBACK
  3484. # endif // SDK
  3485. }
  3486. else
  3487. {
  3488. # if defined (SDK)
  3489. # ifdef GTK_DOWNLOAD_EXTENSION
  3490. ServerName* sname = current_url.GetServerName();
  3491. unsigned short port = current_url.GetServerPort();
  3492. AuthElm* auth = sname->Get_Auth(NULL, (port == 0) ? 80 : port, current_url.GetPath(), current_url.Type(), 0);
  3493. char *auth_credentials = NULL;
  3494. if (auth)
  3495. OP_STATUS status = auth->GetAuthString(&auth_credentials, current_url.GetRep());
  3496. GtkWidget* ow = GTK_WIDGET(((GdkOpWindow*)GetWindow()->GetOpWindow())->GetGtkWidget());
  3497. OP_ASSERT(ow);
  3498. if (ow)
  3499. {
  3500. GtkOperaDownloadExtension* download_extension = GTK_OPERA_DOWNLOAD_EXTENSION(gtk_operawidget_get_extension( GTK_OPERA_WIDGET(ow), GTK_OPERA_DOWNLOAD_EXTENSION_TYPE ));
  3501. if (download_extension)
  3502. g_signal_emit(G_OBJECT(download_extension), gtk_opera_download_extension_signals[GTK_OPERA_DOWNLOAD_EXTENSION_REQUEST], 0,
  3503. current_url.Name(),
  3504. NULL,
  3505. current_url.GetAttribute(URL::KMIME_Type),
  3506. auth_credentials,
  3507. 0,
  3508. OpDocumentListener::UNKNOWN);
  3509. }
  3510. OP_DELETEA(auth_credentials);
  3511. # else // GTK_DOWNLOAD_EXTENSION
  3512. window->GetWindowCommander()->GetDocumentListener()->OnDownloadRequest(
  3513. window->GetWindowCommander(),
  3514. current_url.GetUniName(TRUE,PASSWORD_HIDDEN),
  3515. NULL,
  3516. current_url.GetAttribute(URL::KMIME_Type),
  3517. 0,
  3518. OpDocumentListener::UNKNOWN);
  3519. # endif // GTK_DOWNLOAD_EXTENSION
  3520. # else // SDK
  3521. # if defined (WIC_USE_DOWNLOAD_CALLBACK)
  3522. TransferManagerDownloadCallback * t_tmdc = OP_NEW(TransferManagerDownloadCallback, (this, current_url, viewer, current_action_flag));
  3523. if (!t_tmdc)
  3524. return OpStatus::ERR_NO_MEMORY;
  3525. WindowCommander * wc = window->GetWindowCommander();
  3526. wc->GetDocumentListener()->OnDownloadRequest(wc, t_tmdc);
  3527. OP_BOOLEAN finished = t_tmdc->Execute();
  3528. if(finished == OpBoolean::IS_FALSE)
  3529. SetLoadStat(WAIT_FOR_USER);
  3530. else
  3531. return finished;
  3532. break; // Note: cleaning up window/docman must wait until another
  3533. // entity takes over the download, or not.
  3534. # else // !WIC_USE_DOWNLOAD_CALLBACK
  3535. window->GetWindowCommander()->GetDocumentListener()->OnDownloadRequest(
  3536. window->GetWindowCommander(),
  3537. url_name.CStr(),
  3538. suggested_filename.CStr(),
  3539. current_url.GetAttribute(URL::KMIME_Type).CStr(),
  3540. current_url.GetContentSize(),
  3541. OpDocumentListener::UNKNOWN,
  3542. NULL);
  3543. # endif // !WIC_USE_DOWNLOAD_CALLBACK
  3544. # endif // SDK
  3545. }
  3546. StopLoading(FALSE); //the window is not handling the loading anymore
  3547. if (current_url.Status(TRUE) != URL_LOADING)
  3548. HandleAllLoaded(url_id);
  3549. }
  3550. break;
  3551. #endif // !NO_SAVE_SUPPORT
  3552. case VIEWER_PASS_URL:
  3553. {
  3554. #ifndef NO_EXTERNAL_APPLICATIONS
  3555. if (app && *app)
  3556. {
  3557. current_url.StopLoading(mh);
  3558. stat = g_op_system_info->ExecuteApplication(app,
  3559. current_url.GetAttribute(URL::KUniName_Username_Password_Escaped_NOT_FOR_UI).CStr()); // PASSWORD_SHOW_VERBATIM accepted provisionally
  3560. }
  3561. #endif // !NO_EXTERNAL_APPLICATIONS
  3562. StopLoading(FALSE);
  3563. EndProgressDisplay();
  3564. }
  3565. break;
  3566. case VIEWER_APPLICATION:
  3567. #ifndef NO_EXTERNAL_APPLICATIONS
  3568. if (app && *app)
  3569. {
  3570. OpStatus::Ignore(SetTempDownloadFolder());
  3571. SetLoadStat(WAIT_FOR_LOADING_FINISHED);
  3572. SetApplication(app);
  3573. if (current_url.Status(TRUE) != URL_LOADING)
  3574. HandleAllLoaded(url_id);
  3575. }
  3576. else
  3577. {
  3578. # ifdef WIC_USE_DOWNLOAD_CALLBACK
  3579. TransferManagerDownloadCallback * t_tmdc = OP_NEW(TransferManagerDownloadCallback, (this, current_url, NULL, current_action_flag));
  3580. if (!t_tmdc)
  3581. return OpStatus::ERR_NO_MEMORY;
  3582. window->GetWindowCommander()->GetDocumentListener()->OnDownloadRequest(
  3583. window->GetWindowCommander(), t_tmdc);
  3584. OP_BOOLEAN finished = t_tmdc->Execute();
  3585. if(finished == OpBoolean::IS_FALSE)
  3586. SetLoadStat(WAIT_FOR_USER);
  3587. # else // !WIC_USE_DOWNLOAD_CALLBACK
  3588. SetLoadStat(WAIT_FOR_USER);
  3589. window->AskAboutUnknownDoc(current_url, GetSubWinId());
  3590. # endif // !WIC_USE_DOWNLOAD_CALLBACK
  3591. }
  3592. #endif // !NO_EXTERNAL_APPLICATIONS
  3593. break;
  3594. case VIEWER_REG_APPLICATION:
  3595. case VIEWER_RUN:
  3596. #ifndef NO_EXTERNAL_APPLICATIONS
  3597. OpStatus::Ignore(SetTempDownloadFolder());
  3598. SetLoadStat(WAIT_FOR_LOADING_FINISHED);
  3599. if (current_url.Status(TRUE) != URL_LOADING)
  3600. HandleAllLoaded(url_id);
  3601. #endif // !NO_EXTERNAL_APPLICATIONS
  3602. break;
  3603. #ifdef WEB_HANDLERS_SUPPORT
  3604. case VIEWER_WEB_APPLICATION:
  3605. if (app && *app)
  3606. {
  3607. Viewer* viewer;
  3608. RETURN_IF_ERROR(g_viewers->FindViewerByURL(current_url, viewer, TRUE));
  3609. OP_ASSERT(viewer);
  3610. TempBuffer8 parameter_url8;
  3611. RETURN_IF_ERROR(parameter_url8.AppendURLEncoded(current_url.GetAttribute(URL::KName_With_Fragment_Escaped)));
  3612. OpString parameter_url16;
  3613. RETURN_IF_ERROR(parameter_url16.SetFromUTF8(parameter_url8.GetStorage()));
  3614. OpString target_url_str;
  3615. RETURN_IF_ERROR(target_url_str.Set(app));
  3616. RETURN_IF_ERROR(target_url_str.ReplaceAll(UNI_L("%s"), parameter_url16.CStr(), 1));
  3617. URL target_url = g_url_api->GetURL(current_url, target_url_str.CStr());
  3618. if (!viewer->IsUserDefined() || force_ask_user)
  3619. {
  3620. OpString8 mime;
  3621. RETURN_IF_ERROR(current_url.GetAttribute(URL::KMIME_Type, mime, TRUE));
  3622. WebHandlerCallback* cb = OP_NEW(WebHandlerCallback, (this, current_url, referrer_url, target_url, user_initiated_loading, user_started_loading, viewer->GetDescription(), !force_ask_user));
  3623. RETURN_OOM_IF_NULL(cb);
  3624. RETURN_IF_ERROR(cb->Construct(mime));
  3625. window->GetWindowCommander()->GetDocumentListener()->OnWebHandler(window->GetWindowCommander(), cb);
  3626. StopLoading(FALSE, TRUE);
  3627. }
  3628. else // Open without asking
  3629. OpenURL(target_url, DocumentReferrer(current_url), TRUE, FALSE, user_initiated_loading, FALSE, user_started_loading ? WasEnteredByUser : NotEnteredByUser);
  3630. }
  3631. break;
  3632. #endif // WEB_HANDLERS_SUPPORT
  3633. case VIEWER_PLUGIN:
  3634. case VIEWER_OPERA:
  3635. if (es_pending_unload)
  3636. {
  3637. SetLoadStat(WAIT_FOR_ECMASCRIPT);
  3638. return ESSendPendingUnload(check_if_inline_expired, action == VIEWER_PLUGIN);
  3639. }
  3640. #if defined(SUPPORT_VERIZON_EXTENSIONS) && defined(WIC_ORIENTATION_CHANGE)
  3641. {
  3642. OpString8 verizonHeader;
  3643. verizonHeader.Set( "x-verizon-content");
  3644. current_url.GetAttribute( URL::KHTTPSpecificResponseHeaderL, verizonHeader, TRUE);
  3645. if ( verizonHeader.CompareI( "portrait") == 0)
  3646. window->GetWindowCommander()->GetDocumentListener()->OnOrientationChangeRequest( window->GetWindowCommander(), OpDocumentListener::PORTRAIT);
  3647. else if ( verizonHeader.CompareI( "landscape") == 0)
  3648. window->GetWindowCommander()->GetDocumentListener()->OnOrientationChangeRequest( window->GetWindowCommander(), OpDocumentListener::LANDSCAPE);
  3649. }
  3650. #endif //SUPPORT_VERIZON_EXTENSIONS && WIC_ORIENTATION_CHANGE
  3651. update_this_window = !HandleByOpera(check_if_inline_expired, action == VIEWER_PLUGIN, FALSE, &out_of_memory);
  3652. if (out_of_memory)
  3653. return OpStatus::ERR_NO_MEMORY;
  3654. break;
  3655. case VIEWER_IGNORE_URL:
  3656. //just stop Opera's handling of this URL, no more work required from us
  3657. HandleAllLoaded(current_url.Id(TRUE)); // Clean up and inform everyone else.
  3658. StopLoading(FALSE, TRUE); // force end-progress
  3659. #ifdef SVG_SUPPORT
  3660. // notify svg manager that the element will be ignored
  3661. {
  3662. HTML_Element* embedding_element = GetFrame() ? GetFrame()->GetHtmlElement() : NULL;
  3663. if (embedding_element && embedding_element->GetNsType() == NS_SVG)
  3664. g_svg_manager->HandleInlineIgnored(GetParentDoc(), embedding_element);
  3665. }
  3666. #endif // SVG_SUPPORT
  3667. break;
  3668. case VIEWER_NOT_DEFINED:
  3669. {
  3670. OpString url_name;
  3671. current_url.GetAttribute(URL::KUniName, url_name);
  3672. WindowCommander *wc = GetWindow()->GetWindowCommander();
  3673. wc->GetDocumentListener()->OnUnhandledFiletype(wc, url_name.CStr());
  3674. StopLoading(FALSE, TRUE); // force end-progress
  3675. }
  3676. break;
  3677. case VIEWER_ASK_USER:
  3678. // Allow one (1) "ask_user" that is not caused by a user. Replace any others
  3679. // with a page with a link to the url (ref bug DSK-160957, DSK-172632 and CORE-9298)
  3680. if (!user_initiated_loading)
  3681. {
  3682. if (GetParentDoc() &&
  3683. GetWindow()->HasShownUnsolicitedDownloadDialog()) // Already consumed its chance
  3684. {
  3685. URL parent_frame_url = GetParentDoc()->GetURL();
  3686. URL link_to_content = g_url_api->GetNewOperaURL();
  3687. link_to_content.Unload();
  3688. // Create the placeholder document
  3689. OpSuppressedURL placeholder(link_to_content, current_url, TRUE);
  3690. RETURN_IF_ERROR(placeholder.GenerateData());
  3691. OpenURLOptions options;
  3692. BOOL check_if_expired = FALSE;
  3693. BOOL reload = FALSE;
  3694. OpenURL(link_to_content, GetParentDoc(), check_if_expired, reload, options);
  3695. break; // aborting the download
  3696. }
  3697. else
  3698. {
  3699. GetWindow()->SetHasShownUnsolicitedDownloadDialog(TRUE);
  3700. }
  3701. }
  3702. // fallthrough
  3703. default:
  3704. OP_ASSERT(action != VIEWER_REDIRECT || !"VIEWER_REDIRECT was obsoleted by VIEWER_WEB_APPLICATION");
  3705. # ifdef WIC_USE_DOWNLOAD_CALLBACK
  3706. TransferManagerDownloadCallback * t_tmdc = OP_NEW(TransferManagerDownloadCallback, (this, current_url, NULL, current_action_flag));
  3707. if (!t_tmdc)
  3708. return OpStatus::ERR_NO_MEMORY;
  3709. window->GetWindowCommander()->GetDocumentListener()->OnDownloadRequest(
  3710. window->GetWindowCommander(), t_tmdc);
  3711. OP_BOOLEAN finished = t_tmdc->Execute();
  3712. if(finished == OpBoolean::IS_FALSE)
  3713. SetLoadStat(WAIT_FOR_USER);
  3714. # else // !WIC_USE_DOWNLOAD_CALLBACK
  3715. SetLoadStat(WAIT_FOR_USER);
  3716. window->AskAboutUnknownDoc(current_url, GetSubWinId());
  3717. # endif // !WIC_USE_DOWNLOAD_CALLBACK
  3718. }
  3719. use_current_doc = FALSE;
  3720. g_windowManager->UpdateVisitedLinks(current_url, update_this_window ? NULL : GetWindow());
  3721. if (es_pending_unload)
  3722. OpStatus::Ignore(ESCancelPendingUnload());
  3723. return stat;
  3724. }
  3725. return OpStatus::OK;
  3726. }
  3727. void DocumentManager::HandleUrlMoved(URL_ID url_id, URL_ID moved_to_id)
  3728. {
  3729. URL to_url = current_url.GetAttribute(URL::KMovedToURL, TRUE);
  3730. #ifdef URL_MOVED_EVENT
  3731. OpStringC url_string = to_url.GetAttribute(URL::KUniName);
  3732. WindowCommander *win_com = window->GetWindowCommander();
  3733. win_com->GetLoadingListener()->OnUrlMoved(win_com, url_string.CStr());
  3734. #endif // URL_MOVED_EVENT
  3735. if (!IsURLSuitableSecurityContext(to_url))
  3736. {
  3737. // Redirect to something like a data: url. We need to let the last "real" document in the redirect chain be
  3738. // the origin.
  3739. DropCurrentLoadingOrigin();
  3740. URL url = current_url;
  3741. URL prev_url;
  3742. while (!url.IsEmpty() && !(url == to_url))
  3743. {
  3744. prev_url = url;
  3745. url = url.GetAttribute(URL::KMovedToURL, FALSE);
  3746. }
  3747. if (IsURLSuitableSecurityContext(prev_url))
  3748. current_loading_origin = DocumentOrigin::Make(prev_url);
  3749. }
  3750. NotifyUrlChangedIfAppropriate(to_url);
  3751. #ifdef TRUST_RATING
  3752. if (OpStatus::IsMemoryError(CheckTrustRating(to_url)))
  3753. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  3754. #endif // TRUST_RATING
  3755. }
  3756. #ifndef NO_EXTERNAL_APPLICATIONS
  3757. OP_STATUS DocumentManager::SetTempDownloadFolder()
  3758. {
  3759. OpString filename;
  3760. TRAPD(err, current_url.GetAttributeL(URL::KSuggestedFileName_L, filename, TRUE));
  3761. RETURN_IF_ERROR(err);
  3762. OpString saveto_filename;
  3763. /* This code is fundamentally broken if OPFILE_TEMPDOWNLOAD_FOLDER doesn't
  3764. exist. It should exist anyway, I think, or at least with a different
  3765. condition. This function is called from non-NO_EXTERNAL_APPLICATIONS
  3766. code. Or maybe that code is broken; I don't know. */
  3767. #ifndef NO_EXTERNAL_APPLICATIONS
  3768. RETURN_IF_ERROR(g_folder_manager->GetFolderPath(OPFILE_TEMPDOWNLOAD_FOLDER, saveto_filename));
  3769. #endif // NO_EXTERNAL_APPLICATIONS
  3770. int saveto_len = saveto_filename.Length();
  3771. if (saveto_len > 0 && saveto_filename[saveto_len-1] != PATHSEPCHAR)
  3772. RETURN_IF_ERROR(saveto_filename.Append(PATHSEP));
  3773. RETURN_IF_ERROR(saveto_filename.Append(filename));
  3774. err = CreateUniqueFilename(saveto_filename);
  3775. RETURN_IF_ERROR(err);
  3776. if (saveto_filename.HasContent())
  3777. RETURN_IF_ERROR(current_url.LoadToFile(saveto_filename.CStr()));
  3778. return OpStatus::OK;
  3779. }
  3780. #endif // NO_EXTERNAL_APPLICATIONS
  3781. OP_STATUS DocumentManager::SetSaveDirect(Viewer * viewer, BOOL &can_do)
  3782. {
  3783. can_do = FALSE;
  3784. #ifndef NO_SAVE_SUPPORT
  3785. OpString filename;
  3786. if (viewer->GetSaveToFolder())
  3787. {
  3788. TRAPD(err, current_url.GetAttributeL(URL::KSuggestedFileName_L, filename, TRUE));
  3789. RETURN_IF_ERROR(err);
  3790. OpString saveto_filename;
  3791. RETURN_IF_ERROR(saveto_filename.Set(viewer->GetSaveToFolder()));
  3792. if( saveto_filename.Length() > 0 && saveto_filename[saveto_filename.Length()-1] != PATHSEPCHAR )
  3793. RETURN_IF_ERROR(saveto_filename.Append(PATHSEP));
  3794. RETURN_IF_ERROR(saveto_filename.Append(filename));
  3795. err = CreateUniqueFilename(saveto_filename);
  3796. RETURN_IF_ERROR(err);
  3797. if (saveto_filename.HasContent())
  3798. {
  3799. RETURN_IF_ERROR(current_url.LoadToFile(saveto_filename.CStr()));
  3800. can_do = TRUE;
  3801. }
  3802. }
  3803. #endif // !NO_SAVE_SUPPORT
  3804. return OpStatus::OK;
  3805. }
  3806. void DocumentManager::HandleMultipartReload(URL_ID url_id, BOOL internal_reload)
  3807. {
  3808. FramesDocument* doc = GetCurrentDoc();
  3809. /* If we've calculated that "compatible" history navigation is needed, then
  3810. reloading this document will have observable side-effects, and possibly
  3811. break things. (And it does break test result reporting in the sunspider
  3812. benchmark.) */
  3813. if (doc && doc->GetCompatibleHistoryNavigationNeeded() && internal_reload)
  3814. return;
  3815. if (current_url.Id(TRUE) != url_id || doc && doc->GetURL().IsImage())
  3816. {
  3817. // check frames
  3818. if (doc && doc->HandleLoading(MSG_MULTIPART_RELOAD, url_id, internal_reload) == OpStatus::ERR_NO_MEMORY)
  3819. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  3820. return;
  3821. }
  3822. DM_LoadStat old_load_stat = GetLoadStatus();
  3823. BOOL was_waiting_for_header = (old_load_stat == WAIT_FOR_HEADER);
  3824. // Need to keep the URL used, since HandleAllLoaded sets load_stat to NOT_LOADING
  3825. // which resets our URL_InUse object. Once we set load_stat to WAIT_FOR_HEADER
  3826. // below, the URL will be used again. The temporary URL_IsUse makes sure the use
  3827. // counter doesn't temporarily goes down to zero.
  3828. URL_InUse temporary_use(current_url);
  3829. HandleAllLoaded(url_id, TRUE);
  3830. SetLoadStat(WAIT_MULTIPART_RELOAD);
  3831. SetUserAutoReload(FALSE);
  3832. if (!GetReload() && !internal_reload && !was_waiting_for_header)
  3833. SetReload(TRUE);
  3834. if (old_load_stat == DOC_CREATED)
  3835. if (OpStatus::IsMemoryError(GetCurrentDoc()->HandleLoading(MSG_MULTIPART_RELOAD, url_id, 0)))
  3836. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  3837. #ifdef _WML_SUPPORT_
  3838. if (wml_context)
  3839. wml_context->RestartParsing();
  3840. #endif // _WML_SUPPORT_
  3841. }
  3842. #ifdef _ISHORTCUT_SUPPORT
  3843. static OP_STATUS ReadParseFollowInternetShortcutHelper(uni_char *filename, Window *window)
  3844. {
  3845. TRAPD(status, ReadParseFollowInternetShortcutL(filename, window));
  3846. return status;
  3847. }
  3848. #endif // _ISHORTCUT_SUPPORT
  3849. BOOL DocumentManager::HandleByOpera(BOOL check_if_inline_expired, BOOL use_plugin, BOOL is_user_initiated, BOOL *out_of_memory)
  3850. {
  3851. BOOL oom;
  3852. if (out_of_memory == NULL)
  3853. out_of_memory = &oom;
  3854. *out_of_memory = FALSE;
  3855. URLContentType type = current_url.ContentType();
  3856. FramesDocument* doc = GetCurrentDoc();
  3857. if (GetParentDoc()
  3858. #ifdef SVG_SUPPORT
  3859. && (!frame->GetHtmlElement() || !frame->GetHtmlElement()->IsMatchingType(Markup::HTE_IMG, NS_HTML))
  3860. #endif // SVG_SUPPORT
  3861. ) // this is a frame, check for clickjacking
  3862. {
  3863. // Note that quite similar code exists in
  3864. // HTML_Element::CheckMeta where the <meta http-equiv> is taken care of.
  3865. OpString8 frame_options;
  3866. current_url.GetAttribute(URL::KHTTPFrameOptions, frame_options);
  3867. if (!frame_options.IsEmpty()) // No way to differ between an empty header and no header at all?
  3868. {
  3869. BOOL allow = TRUE;
  3870. if (frame_options.CompareI("deny") == 0)
  3871. allow = FALSE;
  3872. else if (frame_options.CompareI("sameorigin") == 0)
  3873. {
  3874. URL top_doc_url = GetWindow()->DocManager()->GetCurrentDoc()->GetURL();
  3875. if (!current_url.SameServer(top_doc_url) ||
  3876. (top_doc_url.Type() == URL_HTTPS && current_url.Type() == URL_HTTP) ||
  3877. (top_doc_url.Type() == URL_HTTP && current_url.Type() == URL_HTTPS))
  3878. allow = FALSE;
  3879. }
  3880. if (!allow)
  3881. {
  3882. // Nesting a document that prohibits being nested
  3883. URL blocked_page = current_url;
  3884. StopLoading(FALSE /* FALSE = abort immediately*/);
  3885. #ifdef ERROR_PAGE_SUPPORT
  3886. GenerateAndShowClickJackingBlock(blocked_page);
  3887. #endif // ERROR_PAGE_SUPPORT
  3888. return FALSE;
  3889. }
  3890. }
  3891. }
  3892. switch (type)
  3893. {
  3894. #ifdef _MIME_SUPPORT_
  3895. case URL_MIME_CONTENT:
  3896. #ifdef MHTML_ARCHIVE_REDIRECT_SUPPORT
  3897. case URL_MHTML_ARCHIVE:
  3898. #endif
  3899. return FALSE;
  3900. #endif // _MIME_SUPPORT_
  3901. #ifdef _WML_SUPPORT_
  3902. case URL_WML_CONTENT:
  3903. if (window)
  3904. {
  3905. if (wml_context && window->GetURLCameFromAddressField())
  3906. wml_context->SetStatusOn(WS_CLEANHISTORY); // if URL is from address-field, we shall 'clean' the wml history
  3907. else if (!wml_context)
  3908. {
  3909. // find out if the opener window has a wml context
  3910. Window* opener_window = window->GetOpenerWindow();
  3911. if (opener_window)
  3912. {
  3913. WML_Context* old_wc = opener_window->DocManager()->WMLGetContext();
  3914. if (old_wc)
  3915. {
  3916. WMLSetContext(old_wc); // copies the old context to this DocumentManager
  3917. old_wc->SetActiveTask(NULL); // remove the active_task of the origin window
  3918. }
  3919. }
  3920. }
  3921. }
  3922. break;
  3923. #endif //_WML_SUPPORT_
  3924. case URL_UNKNOWN_CONTENT:
  3925. case URL_UNDETERMINED_CONTENT:
  3926. if (!use_plugin)
  3927. current_url.SetAttribute(URL::KForceContentType, URL_TEXT_CONTENT);
  3928. break;
  3929. #ifdef OPERA_SETUP_DOWNLOAD_APPLY_SUPPORT
  3930. case URL_MENU_CONFIGURATION_CONTENT:
  3931. case URL_TOOLBAR_CONFIGURATION_CONTENT:
  3932. case URL_MOUSE_CONFIGURATION_CONTENT:
  3933. case URL_KEYBOARD_CONFIGURATION_CONTENT:
  3934. case URL_SKIN_CONFIGURATION_CONTENT:
  3935. case URL_MULTI_CONFIGURATION_CONTENT:
  3936. #endif // OPERA_SETUP_DOWNLOAD_APPLY_SUPPORT
  3937. #ifdef GADGET_SUPPORT
  3938. case URL_GADGET_INSTALL_CONTENT:
  3939. case URL_UNITESERVICE_INSTALL_CONTENT:
  3940. # ifdef EXTENSION_SUPPORT
  3941. case URL_EXTENSION_INSTALL_CONTENT:
  3942. # endif // EXTENSION_SUPPORT
  3943. #endif // GADGET_SUPPORT
  3944. #ifdef OPERA_SETUP_DOWNLOAD_APPLY_SUPPORT
  3945. {
  3946. # if defined(_KIOSK_MANAGER_)
  3947. if( KioskManager::GetInstance()->GetNoDownload() )
  3948. {
  3949. window->GetDocManagerById(-1)->StopLoading(FALSE);
  3950. window->ResetProgressDisplay();
  3951. window->SetState(NOT_BUSY);
  3952. return TRUE;
  3953. }
  3954. # endif
  3955. SetLoadStat(WAIT_FOR_USER);
  3956. # ifdef GADGET_SUPPORT
  3957. if (type == URL_GADGET_INSTALL_CONTENT
  3958. # ifdef WEBSERVER_SUPPORT
  3959. || type == URL_UNITESERVICE_INSTALL_CONTENT
  3960. # endif // WEBSERVER_SUPPORT
  3961. # ifdef EXTENSION_SUPPORT
  3962. || type == URL_EXTENSION_INSTALL_CONTENT
  3963. # endif // EXTENSION_SUPPORT
  3964. )
  3965. {
  3966. # ifdef WIC_USE_DOWNLOAD_CALLBACK
  3967. TransferManagerDownloadCallback * t_tmdc = OP_NEW(TransferManagerDownloadCallback, (this, current_url, NULL, current_action_flag));
  3968. if (!t_tmdc)
  3969. return OpStatus::ERR_NO_MEMORY;
  3970. OpDocumentListener *listener = window->GetWindowCommander()->GetDocumentListener();
  3971. if(listener)
  3972. {
  3973. listener->OnGadgetInstall(window->GetWindowCommander(), t_tmdc);
  3974. // TransferManagerDownload::Execute() might have been called in OnGadgetInstall, which calls
  3975. // ResetCurrentDownloadRequest(), then current_download_request is NULL
  3976. if (current_download_vector.Find(t_tmdc) == -1)
  3977. {
  3978. window->GetDocManagerById(-1)->StopLoading(FALSE);
  3979. window->ResetProgressDisplay();
  3980. window->SetState(NOT_BUSY);
  3981. }
  3982. else
  3983. {
  3984. OP_BOOLEAN finished = t_tmdc->Execute();
  3985. if(finished == OpBoolean::IS_FALSE)
  3986. SetLoadStat(WAIT_FOR_USER);
  3987. }
  3988. }
  3989. else
  3990. {
  3991. OP_DELETE(t_tmdc); // will implicitly remove itself from the list.
  3992. }
  3993. # else // WIC_USE_DOWNLOAD_CALLBACK
  3994. window->AskAboutUnknownDoc(current_url, GetSubWinId());
  3995. return FALSE;
  3996. # endif // else not WIC_USE_DOWNLOAD_CALLBACK
  3997. }
  3998. else
  3999. # endif // GADGET_SUPPORT
  4000. {
  4001. # ifdef WIC_USE_DOWNLOAD_CALLBACK
  4002. OpDocumentListener *listener = window->GetWindowCommander()->GetDocumentListener();
  4003. if(listener)
  4004. {
  4005. listener->OnSetupInstall(window->GetWindowCommander(), current_url.GetAttribute(URL::KUniName_Username_Password_Hidden_Escaped).CStr(), type);
  4006. }
  4007. # else // WIC_USE_DOWNLOAD_CALLBACK
  4008. window->AskAboutUnknownDoc(current_url, GetSubWinId());
  4009. return FALSE;
  4010. # endif // else not WIC_USE_DOWNLOAD_CALLBACK
  4011. }
  4012. # ifdef WIC_USE_DOWNLOAD_CALLBACK
  4013. window->GetDocManagerById(-1)->StopLoading(FALSE);
  4014. window->ResetProgressDisplay();
  4015. window->SetState(NOT_BUSY);
  4016. return FALSE;
  4017. # endif // WIC_USE_DOWNLOAD_CALLBACK
  4018. }
  4019. break;
  4020. #elif defined GADGET_SUPPORT
  4021. window->AskAboutUnknownDoc(current_url, GetSubWinId());
  4022. return FALSE;
  4023. #endif // GADGET_SUPPORT
  4024. #ifdef _SSL_SUPPORT_
  4025. case URL_PFX_CONTENT:
  4026. case URL_X_X509_USER_CERT:
  4027. case URL_X_X509_CA_CERT:
  4028. case URL_X_PEM_FILE:
  4029. #endif // _SSL_SUPPORT_
  4030. #ifdef _ISHORTCUT_SUPPORT
  4031. case URL_ISHORTCUT_CONTENT: //handle InternetShortcuts
  4032. #endif //_ISHORTCUT_SUPPORT
  4033. #ifdef _BITTORRENT_SUPPORT_
  4034. case URL_P2P_BITTORRENT:
  4035. if(type == URL_P2P_BITTORRENT
  4036. && !g_pcnet->GetIntegerPref(PrefsCollectionNetwork::EnableBitTorrent))
  4037. {
  4038. break;
  4039. }
  4040. #endif
  4041. {
  4042. // If all features above are disabled this will be dead code and cause a
  4043. // warning. Accept it.
  4044. SetLoadStat(WAIT_FOR_LOADING_FINISHED);
  4045. if(current_url.Status(TRUE) != URL_LOADING)
  4046. HandleAllLoaded(current_url.Id());
  4047. return FALSE;
  4048. }
  4049. #ifdef XML_AIT_SUPPORT
  4050. case URL_XML_AIT:
  4051. return FALSE;
  4052. #endif // XML_AIT_SUPPORT
  4053. }
  4054. SetLoadStat(DOC_CREATED);
  4055. if (use_current_doc || (doc && (GetReload() || current_doc_elm->IsPreCreated()) && doc->GetURL() == current_url))
  4056. {
  4057. current_doc_elm->SetIsPreCreated(FALSE);
  4058. if (OpStatus::IsMemoryError(UpdateCurrentDoc(use_plugin, FALSE, is_user_initiated)))
  4059. *out_of_memory = TRUE;
  4060. }
  4061. else
  4062. {
  4063. if (doc && doc->GetURL() == current_url)
  4064. SetUseHistoryNumber(current_doc_elm->Number());
  4065. if (OpStatus::IsMemoryError(SetCurrentDoc(check_if_inline_expired, use_plugin, FALSE, is_user_initiated)))
  4066. *out_of_memory = TRUE;
  4067. }
  4068. /* If we delayed signalling current security state to the UI until we
  4069. actually replaced the current document, then now is the time to actually
  4070. tell the UI. */
  4071. GetWindow()->SignalSecurityState();
  4072. if (*out_of_memory)
  4073. return FALSE;
  4074. if (GetRestartParsing())
  4075. {
  4076. if (OpStatus::IsMemoryError(RestartParsing()))
  4077. {
  4078. *out_of_memory = TRUE;
  4079. return FALSE;
  4080. }
  4081. }
  4082. OP_ASSERT(!GetCurrentDoc() || GetCurrentDoc()->IsCurrentDoc());
  4083. return TRUE;
  4084. }
  4085. BOOL DocumentManager::NeedsProgressBar()
  4086. {
  4087. if (window->IsLoading())
  4088. {
  4089. DocumentTreeIterator iterator(window);
  4090. iterator.SetIncludeEmpty();
  4091. iterator.SetIncludeThis();
  4092. while (iterator.Next())
  4093. {
  4094. DocumentManager* docman = iterator.GetDocumentManager();
  4095. FramesDocument* frames_doc = iterator.GetFramesDocument();
  4096. if (frames_doc)
  4097. {
  4098. if (docman->GetCurrentURL().Type() != URL_JAVASCRIPT &&
  4099. frames_doc->GetURL().Id() != docman->GetCurrentURL().Id())
  4100. return TRUE;
  4101. if (frames_doc->NeedsProgressBar())
  4102. return TRUE;
  4103. }
  4104. else if (docman->GetLoadStatus() != NOT_LOADING)
  4105. return TRUE;
  4106. }
  4107. return FALSE;
  4108. }
  4109. else
  4110. return FALSE;
  4111. }
  4112. void DocumentManager::EndProgressDisplay(BOOL force)
  4113. {
  4114. if (force || !NeedsProgressBar())
  4115. window->EndProgressDisplay();
  4116. }
  4117. OP_STATUS DocumentManager::HandleDocFinished()
  4118. {
  4119. FramesDocument *doc = GetCurrentDoc();
  4120. if (GetLoadStatus() != NOT_LOADING && GetLoadStatus() != DOC_CREATED && doc)
  4121. {
  4122. // We didn't expect this at this time. Just ignore it.
  4123. return OpStatus::OK;
  4124. }
  4125. BOOL was_loading = GetLoadStatus() != NOT_LOADING;
  4126. if (GetLoadStatus() != WAIT_MULTIPART_RELOAD)
  4127. SetLoadStat(NOT_LOADING);
  4128. history_walk = DM_NOT_HIST;
  4129. if (user_started_loading)
  4130. {
  4131. user_started_loading = FALSE;
  4132. pending_url_user_initiated = FALSE;
  4133. }
  4134. EndProgressDisplay();
  4135. OP_STATUS stat = OpStatus::OK;
  4136. if (doc)
  4137. stat = FramesDocument::CheckOnLoad(doc);
  4138. else if (frame)
  4139. stat = FramesDocument::CheckOnLoad(NULL, frame);
  4140. if (OpStatus::IsMemoryError(stat))
  4141. return stat;
  4142. ResetStateFlags();
  4143. if (!was_loading)
  4144. return stat;
  4145. if (doc)
  4146. {
  4147. OpString decoded_fragment;
  4148. OpString original_fragment;
  4149. RETURN_IF_ERROR(GetURLFragment(current_url, decoded_fragment, original_fragment));
  4150. if (decoded_fragment.CStr())
  4151. RETURN_IF_MEMORY_ERROR(doc->SetRelativePos(decoded_fragment.CStr(), original_fragment.CStr(), scroll_to_fragment_in_document_finished));
  4152. scroll_to_fragment_in_document_finished = FALSE;
  4153. // update bookmarks info with parent frame
  4154. FramesDocument *parent = doc->GetParentDoc();
  4155. if (!parent && doc->GetURL().Type() == URL_DATA)
  4156. UpdateSecurityState(FALSE);
  4157. if (!parent)
  4158. parent = doc;
  4159. if (doc->GetVisualDevice())
  4160. doc->GetVisualDevice()->LoadingFinished();
  4161. }
  4162. return stat;
  4163. }
  4164. OP_STATUS DocumentManager::UpdateWindowHistoryAndTitle()
  4165. {
  4166. if (!GetParentDoc())
  4167. if (FramesDocument *doc = GetCurrentDoc())
  4168. {
  4169. OpString doc_title;
  4170. TempBuffer buffer;
  4171. RETURN_IF_ERROR(doc_title.Set(doc->Title(&buffer)));
  4172. OP_STATUS stat = OpStatus::OK;
  4173. if (current_doc_elm)
  4174. stat = current_doc_elm->SetTitle(doc_title.CStr());
  4175. if (OpStatus::IsMemoryError(window->UpdateTitle(FALSE)))
  4176. stat = OpStatus::ERR_NO_MEMORY;
  4177. window->EnsureHistoryLimits();
  4178. #ifdef SHORTCUT_ICON_SUPPORT
  4179. if (doc->Icon() && doc->Icon()->Status(TRUE) == URL_LOADED)
  4180. if (OpStatus::IsMemoryError(window->SetWindowIcon(doc->Icon())))
  4181. stat = OpStatus::ERR_NO_MEMORY;
  4182. #endif // SHORTCUT_ICON_SUPPORT
  4183. return stat;
  4184. }
  4185. return OpStatus::OK;
  4186. }
  4187. #if defined _SSL_SUPPORT_ && !defined _EXTERNAL_SSL_SUPPORT_ && !defined _CERTICOM_SSL_SUPPORT_
  4188. static OP_STATUS
  4189. CreateCertificateInstallerHelper(SSL_Certificate_Installer_Base *&ssl_certificate_installer, URL &url, const SSL_Certificate_Installer_flags &installer_flags, SSL_dialog_config *ssl_dialog_config)
  4190. {
  4191. TRAPD(status, ssl_certificate_installer = g_ssl_api->CreateCertificateInstallerL(url, installer_flags, ssl_dialog_config));
  4192. return status;
  4193. }
  4194. #endif // _SSL_SUPPORT_ && _EXTERNAL_SSL_SUPPORT_ && _CERTICOM_SSL_SUPPORT_
  4195. void DocumentManager::HandleAllLoaded(URL_ID url_id, BOOL multipart_reload)
  4196. {
  4197. if (current_url.Id(TRUE) != url_id)
  4198. {
  4199. // check frames
  4200. if (FramesDocument* doc = GetCurrentDoc())
  4201. if (doc->HandleLoading(MSG_ALL_LOADED, url_id, 0) == OpStatus::ERR_NO_MEMORY)
  4202. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  4203. return;
  4204. }
  4205. if (GetLoadStatus() == WAIT_FOR_USER)
  4206. return;
  4207. URL_InUse temporary_use(current_url);
  4208. SetLoadStat(NOT_LOADING);
  4209. history_walk = DM_NOT_HIST;
  4210. use_current_doc = FALSE;
  4211. if (!multipart_reload)
  4212. EndProgressDisplay();
  4213. #ifdef QUICK
  4214. g_hotlist_manager->OnDocumentLoaded( &current_url, TRUE );
  4215. #endif // QUICK
  4216. BOOL raise_OOM_condition = FALSE;
  4217. OpString filename;
  4218. #if defined _LOCALHOST_SUPPORT_ || !defined RAMCACHE_ONLY
  4219. if (current_url.GetAttribute(URL::KFilePathName_L, filename, TRUE) == OpStatus::ERR_NO_MEMORY )
  4220. raise_OOM_condition = TRUE;
  4221. #endif
  4222. ViewAction act = GetAction();
  4223. // The following cases need url to be located on disk
  4224. switch (act)
  4225. {
  4226. case VIEWER_NOT_DEFINED:
  4227. if (!multipart_reload)
  4228. StopLoading(TRUE, !frame);
  4229. break;
  4230. case VIEWER_OPERA:
  4231. {
  4232. URLContentType url_cnt_type = current_url.ContentType();
  4233. switch (url_cnt_type)
  4234. {
  4235. #ifdef _SSL_SUPPORT_
  4236. case URL_PFX_CONTENT:
  4237. case URL_X_X509_USER_CERT:
  4238. case URL_X_X509_CA_CERT:
  4239. case URL_X_PEM_FILE:
  4240. #if !defined(_EXTERNAL_SSL_SUPPORT_) && !defined(_CERTICOM_SSL_SUPPORT_)
  4241. {
  4242. URL empty_url;
  4243. SSL_dialog_config ssl_dialog_config(window->GetOpWindow(), mh, MSG_DOCHAND_CERTIFICATE_INSTALL, 0, empty_url);
  4244. URL url(current_url);
  4245. SSL_CertificateStore store;
  4246. switch (url_cnt_type)
  4247. {
  4248. case URL_PFX_CONTENT:
  4249. case URL_X_X509_USER_CERT:
  4250. store = SSL_ClientStore;
  4251. break;
  4252. case URL_X_X509_CA_CERT:
  4253. store = SSL_CA_Store;
  4254. break;
  4255. case URL_X_PEM_FILE:
  4256. default:
  4257. store = SSL_ClientOrCA_Store;
  4258. break;
  4259. }
  4260. SSL_Certificate_Installer_flags installer_flags(store, TRUE, FALSE);
  4261. OP_STATUS oom_stat = CreateCertificateInstallerHelper(ssl_certificate_installer, url, installer_flags, &ssl_dialog_config);
  4262. if (!ssl_certificate_installer)
  4263. {
  4264. if (OpStatus::IsMemoryError(oom_stat))
  4265. raise_OOM_condition = TRUE;
  4266. }
  4267. else
  4268. {
  4269. OP_STATUS status = ssl_certificate_installer->StartInstallation();
  4270. if (OpStatus::IsError(status) || ssl_certificate_installer->Finished())
  4271. {
  4272. BOOL install_success = OpStatus::IsSuccess(status) &&
  4273. ssl_certificate_installer->InstallSuccess();
  4274. OP_DELETE(ssl_certificate_installer);
  4275. ssl_certificate_installer = NULL;
  4276. raise_OOM_condition = OpStatus::IsMemoryError(status);
  4277. if (!install_success)
  4278. StopLoading(FALSE);
  4279. EndProgressDisplay(current_url.Status(TRUE) != URL_LOADING);
  4280. }
  4281. else
  4282. queue_messages = TRUE;
  4283. }
  4284. }
  4285. #else
  4286. // Handle EPOC certificate manager here
  4287. #endif // _EXTERNAL_SSL_SUPPORT_
  4288. break;
  4289. #endif // _SSL_SUPPORT_
  4290. #ifdef _BITTORRENT_SUPPORT_
  4291. case URL_P2P_BITTORRENT:
  4292. {
  4293. if(act != VIEWER_NOT_DEFINED && g_pcnet->GetIntegerPref(PrefsCollectionNetwork::EnableBitTorrent))
  4294. {
  4295. BTInfo *info = OP_NEW(BTInfo, ());
  4296. if (info)
  4297. info->OnTorrentAvailable(current_url);
  4298. else
  4299. raise_OOM_condition = TRUE;
  4300. current_url_used.UnsetURL();
  4301. }
  4302. }
  4303. break;
  4304. #endif
  4305. #ifdef _ISHORTCUT_SUPPORT
  4306. case URL_ISHORTCUT_CONTENT: //handle InternetShortcuts
  4307. {
  4308. if (current_url.PrepareForViewing(TRUE) == MSG_OOM_CLEANUP)
  4309. {
  4310. raise_OOM_condition = TRUE;
  4311. break;
  4312. }
  4313. if (OpStatus::IsMemoryError(current_url.GetAttribute(URL::KFilePathName_L, filename, TRUE)))
  4314. {
  4315. raise_OOM_condition = TRUE;
  4316. break;
  4317. }
  4318. window->ResetSecurityStateToUnknown();
  4319. SetAction(VIEWER_NOT_DEFINED);
  4320. /* Internet shortcuts are not allowed inside of frames. CORE-48788. */
  4321. if (GetFrame())
  4322. StopLoading(FALSE, TRUE);
  4323. else if (filename.CStr())
  4324. {
  4325. if (OpStatus::IsMemoryError(ReadParseFollowInternetShortcutHelper(filename.CStr(), window)))
  4326. {
  4327. raise_OOM_condition = TRUE;
  4328. break;
  4329. }
  4330. }
  4331. }
  4332. break;
  4333. #endif // _ISHORTCUT_SUPPORT
  4334. #ifdef OPERA_SETUP_DOWNLOAD_APPLY_SUPPORT
  4335. case URL_SKIN_CONFIGURATION_CONTENT:
  4336. case URL_MULTI_CONFIGURATION_CONTENT:
  4337. case URL_MENU_CONFIGURATION_CONTENT:
  4338. case URL_TOOLBAR_CONFIGURATION_CONTENT:
  4339. case URL_MOUSE_CONFIGURATION_CONTENT:
  4340. case URL_KEYBOARD_CONFIGURATION_CONTENT:
  4341. # ifdef GADGET_SUPPORT
  4342. case URL_GADGET_INSTALL_CONTENT:
  4343. case URL_UNITESERVICE_INSTALL_CONTENT:
  4344. # endif // GADGET_SUPPORT
  4345. # ifdef EXTENSION_SUPPORT
  4346. case URL_EXTENSION_INSTALL_CONTENT:
  4347. # endif // EXTENSION_SUPPORT
  4348. //handled in quick/dialogs/SetupApplyDialog.cpp
  4349. break;
  4350. #endif //OPERA_SETUP_DOWNLOAD_APPLY_SUPPORT
  4351. #ifdef XML_AIT_SUPPORT
  4352. case URL_XML_AIT:
  4353. {
  4354. WindowCommander *wc = GetWindow()->GetWindowCommander();
  4355. AITData ait_data;
  4356. if (OpStatus::IsMemoryError(AITParser::Parse(current_url, ait_data)) ||
  4357. OpStatus::IsMemoryError(wc->GetLoadingListener()->OnAITDocument(wc, &ait_data)))
  4358. raise_OOM_condition = TRUE;
  4359. StopLoading(TRUE);
  4360. }
  4361. break;
  4362. #endif // XML_AIT_SUPPORT
  4363. default:
  4364. /* Just here because all other cases are optional, and a switch statement with no cases but a default generates a stupid warning. */
  4365. case URL_HTML_CONTENT:
  4366. FramesDocument *doc = GetCurrentDoc();
  4367. if (doc)
  4368. {
  4369. if (OpStatus::IsMemoryError(UpdateWindowHistoryAndTitle()))
  4370. raise_OOM_condition = TRUE;
  4371. }
  4372. }
  4373. }
  4374. window->SetState(NOT_BUSY);
  4375. break;
  4376. case VIEWER_ASK_USER:
  4377. // already handled in HandleHeaderLoaded or from the unknown file dialog
  4378. break;
  4379. #ifndef NO_SAVE_SUPPORT
  4380. case VIEWER_SAVE:
  4381. if (current_action_flag.IsSet(ViewActionFlag::SAVE_DIRECTLY))
  4382. EndProgressDisplay(TRUE);
  4383. window->SetState(NOT_BUSY);
  4384. break;
  4385. #endif // NO_SAVE_SUPPORT
  4386. case VIEWER_APPLICATION:
  4387. case VIEWER_REG_APPLICATION:
  4388. case VIEWER_RUN:
  4389. #ifndef NO_EXTERNAL_APPLICATIONS
  4390. if (current_url.PrepareForViewing(TRUE) == MSG_OOM_CLEANUP)
  4391. raise_OOM_condition = TRUE;
  4392. else
  4393. {
  4394. OP_STATUS status = current_url.GetAttribute(URL::KFilePathName_L, filename, TRUE);
  4395. if (OpStatus::IsMemoryError(status))
  4396. raise_OOM_condition = TRUE;
  4397. TempBuffer file_to_execute;
  4398. if (act == VIEWER_APPLICATION)
  4399. {
  4400. // FIXME FIXME FIXME. The syntax of ExecuteApplication is completely undocumented
  4401. // which makes it quite a security risk. See CORE-17810.
  4402. // Here we'll add quotes around the argument assuming arguments are space seperated
  4403. // and trying to prevent a filename from being split into several parts.
  4404. // See for instance DSK-238483.
  4405. if (OpStatus::IsMemoryError(file_to_execute.Append('\"')) ||
  4406. OpStatus::IsMemoryError(file_to_execute.Append(filename.CStr(), filename.Length())) ||
  4407. OpStatus::IsMemoryError(file_to_execute.Append('\"')))
  4408. {
  4409. raise_OOM_condition = TRUE;
  4410. }
  4411. }
  4412. else
  4413. {
  4414. if (OpStatus::IsMemoryError(file_to_execute.Append(filename.CStr(), filename.Length())))
  4415. {
  4416. raise_OOM_condition = TRUE;
  4417. }
  4418. }
  4419. if (!raise_OOM_condition)
  4420. {
  4421. switch (act)
  4422. {
  4423. case VIEWER_APPLICATION:
  4424. {
  4425. OP_STATUS status =
  4426. g_op_system_info->ExecuteApplication(
  4427. current_application,
  4428. file_to_execute.GetStorage(),
  4429. #ifdef WIC_USE_DOWNLOAD_CALLBACK
  4430. TRUE); // This suppress error dialog.
  4431. #else
  4432. FALSE);
  4433. #endif // WIC_USE_DOWNLOAD_CALLBACK
  4434. if (OpStatus::IsMemoryError(status))
  4435. {
  4436. raise_OOM_condition = TRUE;
  4437. }
  4438. // Ask user what to do with downloaded file. See DSK-332652.
  4439. #ifdef WIC_USE_DOWNLOAD_CALLBACK
  4440. else if (OpStatus::IsError(status))
  4441. {
  4442. TransferManagerDownloadCallback * t_tmdc =
  4443. OP_NEW(TransferManagerDownloadCallback,
  4444. (this, current_url, NULL,
  4445. current_action_flag,
  4446. TRUE)); // File is already on the disk.
  4447. status = t_tmdc->Init(filename.CStr());
  4448. if (OpStatus::IsSuccess(status))
  4449. {
  4450. window->GetWindowCommander()->GetDocumentListener()->
  4451. OnDownloadRequest(window->GetWindowCommander(),
  4452. t_tmdc);
  4453. if(t_tmdc->Execute() == OpBoolean::IS_FALSE)
  4454. SetLoadStat(WAIT_FOR_USER);
  4455. }
  4456. else if (OpStatus::IsMemoryError(status))
  4457. raise_OOM_condition = TRUE;
  4458. }
  4459. #endif // WIC_USE_DOWNLOAD_CALLBACK
  4460. break;
  4461. }
  4462. case VIEWER_REG_APPLICATION:
  4463. window->ShellExecute(file_to_execute.GetStorage());
  4464. break;
  4465. case VIEWER_RUN:
  4466. if (OpStatus::IsMemoryError(g_op_system_info->ExecuteApplication(file_to_execute.GetStorage(), UNI_L(""))))
  4467. raise_OOM_condition = TRUE;
  4468. }
  4469. }
  4470. EndProgressDisplay(TRUE);
  4471. }
  4472. #endif // NO_EXTERNAL_APPLICATIONS
  4473. break;
  4474. default:
  4475. window->SetState(NOT_BUSY);
  4476. }
  4477. //if the window is Not intiated by the user and this is the first url the window loads, close it
  4478. //since the data is handled elsewhere.
  4479. if ((act != VIEWER_OPERA && act != VIEWER_NOT_DEFINED) &&
  4480. window->GetOpenerWindow() && window->GetHistoryLen() == 0 && window->CanClose())
  4481. window->Close();
  4482. if (GetLoadStatus() == NOT_LOADING)
  4483. {
  4484. SetUserAutoReload(FALSE);
  4485. SetReload(FALSE);
  4486. SetReplace(FALSE);
  4487. SetUseHistoryNumber(-1);
  4488. SetAction(VIEWER_NOT_DEFINED);
  4489. load_image_only = FALSE;
  4490. save_image_only = FALSE;
  4491. if (!GetCurrentDoc() && GetParentDoc())
  4492. {
  4493. FramesDocument::CheckOnLoad(NULL, frame);
  4494. // Some has to tell the parent that we are finished and there is no document to do it
  4495. if (GetParentDoc()->IsLoaded())
  4496. {
  4497. if (!GetParentDoc()->IsDocTreeFinished())
  4498. {
  4499. if (OpStatus::IsMemoryError(GetParentDoc()->CheckFinishDocument()))
  4500. raise_OOM_condition = TRUE;
  4501. }
  4502. }
  4503. }
  4504. }
  4505. if (raise_OOM_condition)
  4506. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  4507. }
  4508. void DocumentManager::HandleDocumentNotModified(URL_ID url_id)
  4509. {
  4510. BOOL raise_OOM_condition = FALSE;
  4511. if (current_url.Id(TRUE) != url_id)
  4512. {
  4513. // check frames
  4514. FramesDocument* doc = GetCurrentDoc();
  4515. if (doc && doc->HandleLoading(MSG_NOT_MODIFIED, url_id, 0) == OpStatus::ERR_NO_MEMORY )
  4516. raise_OOM_condition = TRUE;
  4517. }
  4518. else
  4519. {
  4520. FramesDocument* doc = GetCurrentDoc();
  4521. BOOL is_loading = window->IsLoading();
  4522. BOOL is_reloading = GetReload();
  4523. BOOL is_redirecting = GetRedirect();
  4524. DM_LoadStat old_load_stat = GetLoadStatus();
  4525. if (is_loading || is_redirecting || !doc || !(doc->GetURL() == current_url))
  4526. {
  4527. if (!is_reloading || is_redirecting)
  4528. {
  4529. if (HandleHeaderLoaded(url_id, TRUE) == OpStatus::ERR_NO_MEMORY)
  4530. raise_OOM_condition = TRUE;
  4531. // The call to HandleHeaderLoaded can result in a new current doc
  4532. FramesDocument *new_current_doc = GetCurrentDoc();
  4533. if (!new_current_doc || doc == new_current_doc)
  4534. HandleAllLoaded(url_id);
  4535. }
  4536. else
  4537. {
  4538. if (doc && doc->IsFrameDoc() && doc->GetURL() == current_url)
  4539. {
  4540. raise_OOM_condition = OpStatus::IsMemoryError(doc->HandleLoading(MSG_NOT_MODIFIED, url_id, 0));
  4541. if (doc->IsLoaded() && GetLoadStatus() != DOC_CREATED)
  4542. HandleAllLoaded(url_id);
  4543. SetLoadStatus(DOC_CREATED);
  4544. }
  4545. else
  4546. {
  4547. if (HandleHeaderLoaded(url_id, TRUE) == OpStatus::ERR_NO_MEMORY)
  4548. raise_OOM_condition = TRUE;
  4549. }
  4550. }
  4551. }
  4552. else
  4553. {
  4554. SetUserAutoReload(FALSE);
  4555. SetReload(FALSE);
  4556. SetRedirect(FALSE);
  4557. SetReplace(FALSE);
  4558. SetUseHistoryNumber(-1);
  4559. SetAction(VIEWER_NOT_DEFINED);
  4560. }
  4561. if (old_load_stat == WAIT_FOR_HEADER || doc && doc->GetURL().Type() == URL_DATA)
  4562. window->DocManager()->UpdateSecurityState(FALSE);
  4563. }
  4564. if (raise_OOM_condition)
  4565. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  4566. }
  4567. static OP_STATUS UpdateOfflineModeHelper(BOOL toggle, BOOL &is_offline)
  4568. {
  4569. TRAPD(status, is_offline = UpdateOfflineModeL(toggle));
  4570. return status;
  4571. }
  4572. #ifdef OPERA_CONSOLE
  4573. static void
  4574. PostNetworkError(URL error_url, long error_code, unsigned windowid)
  4575. {
  4576. if (!g_console->IsLogging())
  4577. return;
  4578. OpConsoleEngine::Message msg(OpConsoleEngine::Network, OpConsoleEngine::Error);
  4579. msg.window = windowid;
  4580. TRAPD(status,
  4581. // Ideally, the URL would be both readable (not escaped) and
  4582. // guaranteed to work when clicked or copy-pasted. In the
  4583. // absence a solution for that, the escaped URL is used.
  4584. error_url.GetAttributeL(URL::KUniName_With_Fragment_Escaped, msg.url);
  4585. g_languageManager->GetStringL(ConvertUrlStatusToLocaleString(error_code), msg.message);
  4586. g_console->PostMessageL(&msg));
  4587. RAISE_IF_MEMORY_ERROR(status);
  4588. }
  4589. #endif // OPERA_CONSOLE
  4590. void
  4591. DocumentManager::SendNetworkErrorCode(Window* window, MH_PARAM_2 user_data)
  4592. {
  4593. /*This code will send the error codes the to the error listener*/
  4594. WindowCommander* window_commander = window->GetWindowCommander();
  4595. OpErrorListener* error_listener = window_commander->GetErrorListener();
  4596. union
  4597. {
  4598. OpErrorListener::HttpError http_error;
  4599. OpErrorListener::FileError file_error;
  4600. OpErrorListener::NetworkError network_error;
  4601. };
  4602. enum
  4603. {
  4604. NoErrorType,
  4605. HttpErrorType,
  4606. FileErrorType,
  4607. NetworkErrorType
  4608. }
  4609. error_type;
  4610. /*We need to translate the network error codes to OpErrorListener error codes */
  4611. switch (user_data)
  4612. {
  4613. /*First we translate http error codes */
  4614. case DH_ERRSTR(SI,ERR_HTTP_PAYMENT_REQUIRED):
  4615. error_type = HttpErrorType;
  4616. http_error = OpErrorListener::EC_HTTP_PAYMENT_REQUIRED;
  4617. break;
  4618. case DH_ERRSTR(SI,ERR_URL_TO_LONG):
  4619. case DH_ERRSTR(SI,ERR_HTTP_REQUEST_URI_TOO_LARGE):
  4620. error_type = HttpErrorType;
  4621. http_error = OpErrorListener::EC_HTTP_REQUEST_URI_TOO_LONG;
  4622. break;
  4623. case DH_ERRSTR(SI,ERR_ILLEGAL_URL):
  4624. error_type = HttpErrorType;
  4625. http_error = OpErrorListener::EC_HTTP_BAD_REQUEST;
  4626. break;
  4627. case DH_ERRSTR(SI,ERR_COMM_HOST_NOT_FOUND):
  4628. case DH_ERRSTR(SI,ERR_COMM_HOST_UNAVAILABLE):
  4629. case DH_ERRSTR(SI,ERR_HTTP_NOT_FOUND):
  4630. error_type = HttpErrorType;
  4631. http_error = OpErrorListener::EC_HTTP_NOT_FOUND;
  4632. break;
  4633. case DH_ERRSTR(SI,ERR_HTTP_SERVER_ERROR):
  4634. error_type = HttpErrorType;
  4635. http_error = OpErrorListener::EC_HTTP_INTERNAL_SERVER_ERROR;
  4636. break;
  4637. case DH_ERRSTR(SI,ERR_NO_CONTENT):
  4638. error_type = HttpErrorType;
  4639. http_error = OpErrorListener::EC_HTTP_NO_CONTENT;
  4640. break;
  4641. case DH_ERRSTR(SI,ERR_HTTP_RESET_CONTENT):
  4642. error_type = HttpErrorType;
  4643. http_error = OpErrorListener::EC_HTTP_RESET_CONTENT;
  4644. break;
  4645. case DH_ERRSTR(SI,ERR_COMM_BLOCKED_URL):
  4646. case DH_ERRSTR(SI,ERR_HTTP_NO_CONTENT):
  4647. error_type = HttpErrorType;
  4648. http_error = OpErrorListener::EC_HTTP_NO_CONTENT;
  4649. break;
  4650. case DH_ERRSTR(SI,ERR_HTTP_FORBIDDEN):
  4651. error_type = HttpErrorType;
  4652. http_error = OpErrorListener::EC_HTTP_FORBIDDEN;
  4653. break;
  4654. case DH_ERRSTR(SI,ERR_HTTP_METHOD_NOT_ALLOWED):
  4655. error_type = HttpErrorType;
  4656. http_error = OpErrorListener::EC_HTTP_METHOD_NOT_ALLOWED;
  4657. break;
  4658. case DH_ERRSTR(SI,ERR_HTTP_NOT_ACCEPTABLE):
  4659. error_type = HttpErrorType;
  4660. http_error = OpErrorListener::EC_HTTP_NOT_ACCEPTABLE;
  4661. break;
  4662. case DH_ERRSTR(SI,ERR_HTTP_TIMEOUT):
  4663. error_type = HttpErrorType;
  4664. http_error = OpErrorListener::EC_HTTP_REQUEST_TIMEOUT;
  4665. break;
  4666. case DH_ERRSTR(SI,ERR_HTTP_CONFLICT):
  4667. error_type = HttpErrorType;
  4668. http_error = OpErrorListener::EC_HTTP_CONFLICT;
  4669. break;
  4670. case DH_ERRSTR(SI,ERR_HTTP_GONE):
  4671. error_type = HttpErrorType;
  4672. http_error = OpErrorListener::EC_HTTP_GONE;
  4673. break;
  4674. case DH_ERRSTR(SI,ERR_HTTP_LENGTH_REQUIRED):
  4675. error_type = HttpErrorType;
  4676. http_error = OpErrorListener::EC_HTTP_LENGTH_REQUIRED;
  4677. break;
  4678. case DH_ERRSTR(SI,ERR_HTTP_PRECOND_FAILED):
  4679. error_type = HttpErrorType;
  4680. http_error = OpErrorListener::EC_HTTP_PRECONDITION_FAILED;
  4681. break;
  4682. case DH_ERRSTR(SI,ERR_HTTP_REQUEST_ENT_TOO_LARGE):
  4683. error_type = HttpErrorType;
  4684. http_error = OpErrorListener::EC_HTTP_REQUEST_ENTITY_TOO_LARGE;
  4685. break;
  4686. case DH_ERRSTR(SI,ERR_HTTP_UNSUPPORTED_MEDIA_TYPE):
  4687. error_type = HttpErrorType;
  4688. http_error = OpErrorListener::EC_HTTP_UNSUPPORTED_MEDIA_TYPE;
  4689. break;
  4690. case DH_ERRSTR(SI,ERR_HTTP_NOT_IMPLEMENTED):
  4691. error_type = HttpErrorType;
  4692. http_error = OpErrorListener::EC_HTTP_NOT_IMPLEMENTED;
  4693. break;
  4694. case DH_ERRSTR(SI,ERR_HTTP_BAD_GATEWAY):
  4695. error_type = HttpErrorType;
  4696. http_error = OpErrorListener::EC_HTTP_BAD_GATEWAY;
  4697. break;
  4698. case DH_ERRSTR(SI,ERR_HTTP_GATEWAY_TIMEOUT):
  4699. error_type = HttpErrorType;
  4700. http_error = OpErrorListener::EC_HTTP_GATEWAY_TIMEOUT;
  4701. break;
  4702. case DH_ERRSTR(SI,ERR_HTTP_VERSION_NOT_SUPPORTED):
  4703. error_type = HttpErrorType;
  4704. http_error = OpErrorListener::EC_HTTP_HTTP_VERSION_NOT_SUPPORTED;
  4705. break;
  4706. case DH_ERRSTR(SI,ERR_HTTP_SERVICE_UNAVAILABLE):
  4707. error_type = HttpErrorType;
  4708. http_error = OpErrorListener::EC_HTTP_SERVICE_UNAVAILABLE;
  4709. break;
  4710. /* file errors */
  4711. case DH_ERRSTR(SI,ERR_FILE_CANNOT_OPEN):
  4712. error_type = FileErrorType;
  4713. file_error = OpErrorListener::EC_FILE_REFUSED;
  4714. break;
  4715. case DH_ERRSTR(SI,ERR_FILE_DOES_NOT_EXIST):
  4716. error_type = FileErrorType;
  4717. file_error = OpErrorListener::EC_FILE_NOT_FOUND;
  4718. break;
  4719. /* generic network errors */
  4720. case DH_ERRSTR(SI,ERR_COMM_NETWORK_UNREACHABLE):
  4721. case DH_ERRSTR(SI,ERR_NETWORK_PROBLEM):
  4722. case DH_ERRSTR(SI,ERR_COMM_CONNECT_FAILED):
  4723. error_type = NetworkErrorType;
  4724. network_error = OpErrorListener::EC_NET_CONNECTION;
  4725. break;
  4726. default:
  4727. error_type = NoErrorType;
  4728. break;
  4729. }
  4730. switch (error_type)
  4731. {
  4732. case HttpErrorType:
  4733. error_listener->OnHttpError(window_commander, http_error);
  4734. break;
  4735. case FileErrorType:
  4736. error_listener->OnFileError(window_commander, file_error);
  4737. break;
  4738. case NetworkErrorType:
  4739. error_listener->OnNetworkError(window_commander, network_error);
  4740. break;
  4741. }
  4742. }
  4743. #ifdef ERROR_PAGE_SUPPORT
  4744. static BOOL IsCrossNetworkError(MH_PARAM_2 user_data)
  4745. {
  4746. return user_data == Str::S_MSG_CROSS_NETWORK_INTRANET_LOCALHOST ||
  4747. user_data == Str::S_MSG_CROSS_NETWORK_INTERNET_LOCALHOST ||
  4748. user_data == Str::S_MSG_CROSS_NETWORK_INTERNET_INTRANET;
  4749. }
  4750. #endif // ERROR_PAGE_SUPPORT
  4751. void DocumentManager::HandleLoadingFailed(URL_ID url_id, MH_PARAM_2 user_data)
  4752. {
  4753. BOOL raise_OOM_condition = FALSE;
  4754. if (url_id == current_url.Id() || url_id == current_url.Id(TRUE))
  4755. {
  4756. ViewAction saved_action = GetAction(); // Continue download correctly after Offline mode alert. johan@opera.com
  4757. SetAction(VIEWER_NOT_DEFINED);
  4758. URL final_url = current_url.GetAttribute(URL::KMovedToURL, TRUE);
  4759. URL new_url;
  4760. if (final_url.IsEmpty())
  4761. final_url = current_url;
  4762. BOOL stop_loading_document = TRUE;
  4763. BOOL execute_redirect = FALSE;
  4764. if (OpStatus::IsError(URL_Manager::ManageTCPReset(final_url, new_url, user_data, execute_redirect)))
  4765. return;
  4766. /** Redirect attempted as a counter measure to a TCP Reset (CORE-45283).
  4767. Long story short, if we receive a TCP RST on a small packet, for example a redirect, the
  4768. Windows TCP stack usually will lose the content. Linux does not have the problem.
  4769. In an ideal world, we would fix it on the Network layer at a platform level.
  4770. The problem is that all the working methods (blocking sockets, not blocking synchronous sockets
  4771. with and without overlapped I/O, completion routine and possibly completion ports) are not suitable
  4772. for Opera, as they require additional threads or a call to SleepEx().
  4773. For some reasons, it looks like asynchronous sockets (both with and without overlapped I/O) are not able to cope with this problem.
  4774. So we decided to isolate the problem and attempt a redirect.
  4775. For example: if http://skandiabanken.no fails with a reset, http://www.skandiabanken.no is attempted.
  4776. This fixes CORE-45283 and possibly other similar cases.
  4777. */
  4778. if (execute_redirect)
  4779. {
  4780. DocumentReferrer referrer;
  4781. OpenURL(new_url, referrer, FALSE, FALSE);
  4782. return;
  4783. }
  4784. if (user_data == DH_ERRSTR(SI,ERR_COMM_BLOCKED_URL))
  4785. if (FramesDocElm *frame = GetFrame())
  4786. if (HTML_Element *element = frame->GetHtmlElement())
  4787. if (!element->IsMatchingType(HE_FRAME, NS_HTML))
  4788. /**
  4789. * In here, the URL was blocked by the content blocker
  4790. * and is inside an iframe or object (frames don't count),
  4791. * so we don't load the error page and let the iframe
  4792. * be hidden.
  4793. */
  4794. user_data = DH_ERRSTR(SI,ERR_HTTP_NO_CONTENT);
  4795. if (user_data == DH_ERRSTR(SI,ERR_HTTP_RESET_CONTENT))
  4796. {
  4797. FramesDocument* doc = GetCurrentDoc();
  4798. if (doc)
  4799. doc->ResetForm(1); // FIXME: Reset all forms, not only the first. Double check specs.
  4800. }
  4801. else if (user_data == DH_ERRSTR(SI,ERR_HTTP_NO_CONTENT))
  4802. {
  4803. if (final_url.Type() == URL_JAVASCRIPT && GetCurrentDoc())
  4804. {
  4805. // Javascript urls creating no content ends up here possibly without
  4806. // finishing or sending onload events.
  4807. GetCurrentDoc()->CheckFinishDocument();
  4808. // The javascript URL has finished, but don't stop the document (CORE-33876.)
  4809. stop_loading_document = FALSE;
  4810. }
  4811. }
  4812. else if (user_data == DH_ERRSTR(SI, ERR_SSL_ERROR_HANDLED))
  4813. {
  4814. if (DisplayContentIfAvailable(final_url, url_id, user_data))
  4815. return;
  4816. }
  4817. else if (!GetUserAutoReload())
  4818. {
  4819. URL_InUse temporary_url(current_url); // to avoid that final_url gets deleted when current_url is
  4820. //The following code was moved from Window::MessErrorURL
  4821. //When user is prompted to enter Online mode, the page should continue loading if
  4822. //answer is yes.
  4823. Window::OnlineMode online_mode = window->GetOnlineMode();
  4824. if (user_data == DH_ERRSTR(SI,ERR_COMM_HOST_NOT_FOUND) &&
  4825. online_mode != Window::ONLINE && online_mode != Window::DENIED)
  4826. {
  4827. SetAction(saved_action);
  4828. SetWaitingForOnlineUrl(final_url);
  4829. if (online_mode == Window::OFFLINE)
  4830. {
  4831. if (OpStatus::IsMemoryError(window->QueryGoOnline(&final_url)))
  4832. raise_OOM_condition = TRUE;
  4833. }
  4834. }
  4835. else
  4836. {
  4837. URL ref_url;
  4838. SendNetworkErrorCode( window, user_data );
  4839. #ifdef ERROR_PAGE_SUPPORT
  4840. # ifdef REDIRECT_ON_ERROR
  4841. // show Opera finder page if;
  4842. //1. the preference is ON
  4843. //2. this is the top-frame
  4844. //3. there is no server errormessage
  4845. //4. there is no protocol specified in the original typed string
  4846. //5. the failed server is not the lookup server
  4847. if (g_pcnet->GetIntegerPref(PrefsCollectionNetwork::EnableHostNameWebLookup)
  4848. && !parent_doc
  4849. && !final_url.GetAttribute(URL::KInternalErrorString))
  4850. {
  4851. OpString *typed_in = GetWindow()->GetTypedInUrl();
  4852. if (!typed_in->IsEmpty() && KNotFound == typed_in->FindFirstOf(':')
  4853. && KNotFound == typed_in->FindFirstOf('/'))
  4854. {
  4855. ServerName* sname = final_url.GetServerName();
  4856. OpStringC lookup_adr = g_pcnet->GetStringPref(
  4857. PrefsCollectionNetwork::HostNameWebLookupAddress,
  4858. sname);
  4859. const uni_char* failedDomain = sname ? sname->UniName() : NULL;
  4860. if (failedDomain && !lookup_adr.IsEmpty()
  4861. && KNotFound == lookup_adr.Find(failedDomain))
  4862. {
  4863. OpString lookup_str;
  4864. OP_STATUS oom;
  4865. if (KNotFound != lookup_adr.Find("%s"))
  4866. {
  4867. oom = lookup_str.AppendFormat(lookup_adr.CStr(), typed_in->CStr());
  4868. }
  4869. else
  4870. {
  4871. oom = lookup_str.AppendFormat(UNI_L("%s%s"), lookup_adr.CStr(), typed_in->CStr());
  4872. }
  4873. if (OpStatus::IsMemoryError(oom))
  4874. {
  4875. RaiseCondition(oom);
  4876. return;
  4877. }
  4878. URL lookup_url = g_url_api->GetURL(lookup_str.CStr());
  4879. OpenURL(lookup_url, DocumentReferrer(ref_url), FALSE, FALSE);
  4880. return;
  4881. }
  4882. }
  4883. }
  4884. # endif // REDIRECT_ON_ERROR
  4885. BOOL platform_did_the_error_report = window->HandleLoadingFailed(
  4886. #ifdef HC_CAP_ERRENUM_AS_STRINGENUM
  4887. static_cast<Str::LocaleString>(user_data),
  4888. #else
  4889. ConvertUrlStatusToLocaleString(user_data),
  4890. #endif
  4891. final_url);
  4892. if (!platform_did_the_error_report)
  4893. {
  4894. if (IsCrossNetworkError(user_data))
  4895. {
  4896. GenerateAndShowCrossNetworkErrorPage(final_url, static_cast<Str::LocaleString>(user_data));
  4897. error_page_shown = TRUE;
  4898. }
  4899. else
  4900. if (DisplayContentIfAvailable(final_url, final_url.Id(), user_data))
  4901. {
  4902. # ifdef OPERA_CONSOLE
  4903. PostNetworkError(final_url, user_data, GetWindow()->Id());
  4904. # endif // OPERA_CONSOLE
  4905. }
  4906. else
  4907. {
  4908. URL error_page(final_url);
  4909. #ifdef AB_ERROR_SEARCH_FORM
  4910. const uni_char *user_text = GetWindow()->GetTypedInUrl()->CStr();
  4911. #else
  4912. const uni_char *user_text = NULL;
  4913. #endif //AB_ERROR_SEARCH_FORM
  4914. SetAction(VIEWER_OPERA);
  4915. error_page.SetAttribute(URL::KForceContentType, URL_HTML_CONTENT);
  4916. BOOL show_search_form = !GetFrame() && user_text;
  4917. if (OpStatus::IsMemoryError(g_url_api->GenerateErrorPage(error_page, user_data, &current_url, show_search_form, user_text)))
  4918. raise_OOM_condition = TRUE;
  4919. SetCurrentURL(error_page, FALSE);
  4920. // Now make sure we load the new data. Setting the state to
  4921. // WAIT_FOR_HEADER seems most right
  4922. SetLoadStatus(WAIT_FOR_HEADER); // Load the new document, bypassing the WAIT_FOR_HEADER state
  4923. error_page_shown = TRUE;
  4924. if (OpStatus::IsMemoryError(HandleDataLoaded(error_page.Id(TRUE))))
  4925. raise_OOM_condition = TRUE;
  4926. }
  4927. return;
  4928. }
  4929. #endif // ERROR_PAGE_SUPPORT
  4930. }
  4931. }
  4932. if (!raise_OOM_condition && GetLoadStatus() == DOC_CREATED)
  4933. {
  4934. StopLoading(TRUE);
  4935. return;
  4936. }
  4937. if (es_pending_unload)
  4938. OpStatus::Ignore(ESCancelPendingUnload());
  4939. if (stop_loading_document)
  4940. StopLoading(TRUE, !GetFrame());
  4941. else
  4942. SetLoadStat(NOT_LOADING);
  4943. EndProgressDisplay();
  4944. if (FramesDocElm *frame = GetFrame())
  4945. FramesDocument::CheckOnLoad(NULL, frame);
  4946. else if (FramesDocument* doc = GetCurrentDoc())
  4947. SetCurrentURL(doc->GetURL(), FALSE);
  4948. }
  4949. else
  4950. {
  4951. FramesDocument* doc = GetCurrentDoc();
  4952. if (doc && doc->HandleLoading(MSG_URL_LOADING_FAILED, url_id, user_data) == OpStatus::ERR_NO_MEMORY)
  4953. raise_OOM_condition = TRUE;
  4954. }
  4955. if (raise_OOM_condition)
  4956. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  4957. }
  4958. OP_STATUS DocumentManager::HandleLoading(OpMessage msg, URL_ID url_id, MH_PARAM_2 user_data)
  4959. {
  4960. OP_PROBE6(OP_PROBE_DOCUMENTMANAGER_HANDLELOADING);
  4961. if (queue_messages)
  4962. {
  4963. if (QueuedMessageElm *last = (QueuedMessageElm *) queued_messages.Last())
  4964. if (last->msg == msg && last->url_id == url_id && last->user_data == user_data)
  4965. return OpStatus::OK;
  4966. if (QueuedMessageElm *elm = OP_NEW(QueuedMessageElm, ()))
  4967. {
  4968. elm->msg = (OpMessage) msg;
  4969. elm->url_id = url_id;
  4970. elm->user_data = user_data;
  4971. elm->Into(&queued_messages);
  4972. elm->target_url.SetURL(current_url_reserved);
  4973. }
  4974. else
  4975. return OpStatus::ERR_NO_MEMORY;
  4976. return OpStatus::OK;
  4977. }
  4978. if (is_handling_message || is_clearing || GetLoadStatus() == WAIT_FOR_USER)
  4979. return OpStatus::OK;
  4980. #ifdef _PRINT_SUPPORT_
  4981. if (print_preview_doc && window->GetPreviewMode())
  4982. return OpStatus::OK;
  4983. #endif // _PRINT_SUPPORT_
  4984. OP_STATUS stat = OpStatus::OK;
  4985. is_handling_message = TRUE;
  4986. if (url_id == current_url.Id(TRUE) && GetLoadStatus() == WAIT_MULTIPART_RELOAD)
  4987. {
  4988. /* After MSG_MULTIPART_RELOAD message: If message is MSG_URL_DATA_LOADED
  4989. and the URL has stopped loading, there won't be another body part
  4990. after all, and we're actually done loading. If message is
  4991. MSG_URL_DATA_LOADED and the URL is still loading, ignore it as
  4992. suggested in documentation in url/url2.h. Otherwise revert to
  4993. WAIT_FOR_HEADER state in preperation to load a new body part. */
  4994. if (msg == MSG_URL_DATA_LOADED)
  4995. {
  4996. if (current_url.Status(TRUE) != URL_LOADING)
  4997. {
  4998. SetLoadStatus(DOC_CREATED);
  4999. FramesDocument *doc = GetCurrentDoc();
  5000. if (!doc || doc->IsLoaded())
  5001. EndProgressDisplay();
  5002. }
  5003. is_handling_message = FALSE;
  5004. return OpStatus::OK;
  5005. }
  5006. else
  5007. {
  5008. if (FramesDocument *doc = GetCurrentDoc())
  5009. if (doc->StopLoading(FALSE) == OpStatus::ERR_NO_MEMORY)
  5010. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  5011. SetLoadStatus(WAIT_FOR_HEADER);
  5012. }
  5013. }
  5014. #ifdef AB_ERROR_SEARCH_FORM
  5015. //After this function quits, the text is deleted because it's not going to be used anymore
  5016. AutoEmptyOpString user_text_anchor(GetWindow()->GetTypedInUrl());
  5017. #endif //AB_ERROR_SEARCH_FORM
  5018. switch (msg)
  5019. {
  5020. case MSG_URL_DATA_LOADED:
  5021. if (GetRestartParsing())
  5022. {
  5023. OP_STATUS parse_status = RestartParsing();
  5024. if (OpStatus::IsMemoryError(parse_status))
  5025. {
  5026. is_handling_message = FALSE;
  5027. return parse_status;
  5028. }
  5029. }
  5030. if (!OpStatus::IsError(stat))
  5031. stat = HandleDataLoaded(url_id);
  5032. break;
  5033. case MSG_HEADER_LOADED:
  5034. stat = HandleHeaderLoaded(url_id, TRUE);
  5035. break;
  5036. case MSG_MULTIPART_RELOAD:
  5037. HandleMultipartReload(url_id, (user_data != 0 ? TRUE : FALSE));
  5038. break;
  5039. case MSG_ALL_LOADED:
  5040. HandleAllLoaded(url_id);
  5041. break;
  5042. case MSG_NOT_MODIFIED:
  5043. HandleDocumentNotModified(url_id);
  5044. break;
  5045. case MSG_URL_LOADING_FAILED:
  5046. HandleLoadingFailed(url_id, user_data);
  5047. break;
  5048. case MSG_URL_MOVED:
  5049. HandleUrlMoved(url_id, (URL_ID)user_data);
  5050. break;
  5051. }
  5052. is_handling_message = FALSE;
  5053. return stat;
  5054. }
  5055. OP_STATUS DocumentManager::RestartParsing()
  5056. {
  5057. SetRestartParsing(FALSE);
  5058. #ifdef _WML_SUPPORT_
  5059. if (wml_context)
  5060. {
  5061. RETURN_IF_MEMORY_ERROR(wml_context->RestartParsing());
  5062. }
  5063. #endif // _WML_SUPPORT_
  5064. GetCurrentDoc()->StopLoading(FALSE, TRUE, TRUE);
  5065. OP_STATUS stat = UpdateCurrentDoc(FALSE, TRUE, FALSE);
  5066. OP_ASSERT(!GetCurrentDoc() || GetCurrentDoc()->IsCurrentDoc());
  5067. return stat;
  5068. }
  5069. void DocumentManager::UpdateSecurityState(BOOL include_loading_docs)
  5070. {
  5071. // NOT_LOADING and DOC_CREATED are the states that might have exisiting
  5072. // content. DOC_CREATED could (when walking in history for instance) be
  5073. // a mix of old content and content we're loading the normal way
  5074. // and we have to check the old content.
  5075. if (include_loading_docs ||
  5076. GetLoadStatus() == NOT_LOADING || GetLoadStatus() == DOC_CREATED)
  5077. {
  5078. if (FramesDocument* doc = GetCurrentDoc())
  5079. doc->UpdateSecurityState(include_loading_docs);
  5080. }
  5081. }
  5082. void DocumentManager::SetReload(BOOL value)
  5083. {
  5084. if (!reload != !value)
  5085. {
  5086. reload = reload_document = value;
  5087. conditionally_request_document = !value;
  5088. reload_inlines = FALSE;
  5089. conditionally_request_inlines = TRUE;
  5090. }
  5091. was_reloaded = reload;
  5092. }
  5093. void DocumentManager::SetReloadFlags(BOOL reload_document0, BOOL conditionally_request_document0, BOOL reload_inlines0, BOOL conditionally_request_inlines0)
  5094. {
  5095. reload_document = reload_document0;
  5096. conditionally_request_document = conditionally_request_document0;
  5097. reload_inlines = reload_inlines0;
  5098. were_inlines_reloaded = reload_inlines0;
  5099. conditionally_request_inlines = conditionally_request_inlines0;
  5100. were_inlines_requested_conditionally = conditionally_request_inlines0;
  5101. }
  5102. #ifdef OPERA_CONSOLE
  5103. void DocumentManager::PostURLErrorToConsole(URL& url, Str::LocaleString error_message)
  5104. {
  5105. if (!g_console->IsLogging())
  5106. return;
  5107. BOOL raise_oom = FALSE;
  5108. OpConsoleEngine::Message msg(OpConsoleEngine::Network, OpConsoleEngine::Error);
  5109. msg.window = GetWindow()->Id();
  5110. // Eventually it would be nice to unescape the url to make it more readable, but then we need to
  5111. // get the decoding to do it correctly with respect to charset encodings. See bug 250545
  5112. OP_STATUS check = url.GetAttribute(URL::KUniName_With_Fragment_Escaped, msg.url);
  5113. if (OpStatus::IsSuccess(check))
  5114. {
  5115. check = g_languageManager->GetString(error_message, msg.message);
  5116. if (OpStatus::IsSuccess(check))
  5117. {
  5118. TRAP(check, g_console->PostMessageL(&msg));
  5119. raise_oom = check == OpStatus::ERR_NO_MEMORY;
  5120. }
  5121. else
  5122. raise_oom = check == OpStatus::ERR_NO_MEMORY;
  5123. }
  5124. else
  5125. raise_oom = check == OpStatus::ERR_NO_MEMORY;
  5126. if (raise_oom)
  5127. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  5128. }
  5129. #endif // OPERA_CONSOLE
  5130. #ifdef ON_DEMAND_PLUGIN
  5131. static OP_STATUS ComposePlacholderStr(OpString &placeholder_str, const uni_char *folder)
  5132. {
  5133. OpString file;
  5134. RETURN_IF_MEMORY_ERROR(file.Set(folder));
  5135. RETURN_IF_MEMORY_ERROR(file.Append("missingplugin.svg"));
  5136. TRAPD(status, g_url_api->ResolveUrlNameL(file.CStr(), placeholder_str));
  5137. return status;
  5138. }
  5139. static void CreatePluginPlaceholderUrl(const URL& parent_url, URL &placeholder_url)
  5140. {
  5141. // For plugin placeholders, pretend that this isn't a plugin and replace the
  5142. // current url with the url to the placeholder. This makes us load a
  5143. // document with that url.
  5144. BOOL use_image_placeholder = g_pcdisplay->GetIntegerPref(PrefsCollectionDisplay::EnableOnDemandPluginPlaceholder);
  5145. if (use_image_placeholder)
  5146. {
  5147. OpString placholder_url_str;
  5148. OpString img_folder_name;
  5149. OP_STATUS err = g_folder_manager->GetFolderPath(OPFILE_IMAGE_FOLDER, img_folder_name);
  5150. if (OpStatus::IsSuccess(err) &&
  5151. OpStatus::IsSuccess(ComposePlacholderStr(placholder_url_str, img_folder_name)))
  5152. {
  5153. // Change current_url
  5154. placeholder_url = g_url_api->GetURL(placholder_url_str.CStr());
  5155. // Make current url unique so that our message
  5156. // handler is notified about incoming data,
  5157. // regardless if the url is loaded for other
  5158. // plugins simultaneously.
  5159. g_url_api->MakeUnique(placeholder_url);
  5160. // Set the URL of the plugin placeholder the same security status as its parent URL has.
  5161. placeholder_url.SetAttribute(URL::KSecurityStatus, parent_url.GetAttribute(URL::KSecurityStatus, TRUE));
  5162. return;
  5163. }
  5164. }
  5165. // Document will not be painted. Load as little as possible.
  5166. placeholder_url = g_url_api->GetURL("about:blank");
  5167. }
  5168. #endif // ON_DEMAND_PLUGIN
  5169. BOOL DocumentManager::IsRelativeJump(URL url)
  5170. {
  5171. if (FramesDocument *current_doc = GetCurrentDoc())
  5172. {
  5173. URL current_doc_url = current_doc->GetURL();
  5174. if (url.RelName())
  5175. {
  5176. if (url == current_doc_url)
  5177. return TRUE;
  5178. else if (current_doc_url.GetAttribute(URL::KUnique, TRUE) &&
  5179. !url.GetAttribute(URL::KUnique, TRUE))
  5180. {
  5181. OpString8 url_string;
  5182. if (OpStatus::IsSuccess(url.GetAttribute(URL::KName_Username_Password_NOT_FOR_UI, url_string, TRUE)))
  5183. if (current_doc_url.GetAttribute(URL::KName_Username_Password_NOT_FOR_UI, TRUE).Compare(url_string) == 0)
  5184. return TRUE;
  5185. }
  5186. }
  5187. }
  5188. return FALSE;
  5189. }
  5190. BOOL
  5191. DocumentManager::SignalOnNewPage(OpViewportChangeReason reason)
  5192. {
  5193. if (!GetParentDoc())
  5194. {
  5195. ViewportController* controller = GetWindow()->GetViewportController();
  5196. controller->GetViewportInfoListener()->OnNewPage(controller,
  5197. reason,
  5198. current_doc_elm ? current_doc_elm->GetID() : HistoryIdNotSet);
  5199. return TRUE;
  5200. }
  5201. return FALSE;
  5202. }
  5203. void
  5204. DocumentManager::CheckOnNewPageReady()
  5205. {
  5206. if (waiting_for_document_ready && !GetVisualDevice()->IsLocked())
  5207. {
  5208. waiting_for_document_ready = FALSE;
  5209. ViewportController* controller = GetWindow()->GetViewportController();
  5210. controller->GetViewportInfoListener()->OnNewPageReady(controller);
  5211. }
  5212. }
  5213. DocumentManager::OpenURLOptions::OpenURLOptions()
  5214. : user_initiated(FALSE),
  5215. create_doc_now(FALSE),
  5216. entered_by_user(NotEnteredByUser),
  5217. is_walking_in_history(FALSE),
  5218. es_terminated(FALSE),
  5219. called_externally(FALSE),
  5220. bypass_url_access_check(FALSE),
  5221. ignore_fragment_id(FALSE),
  5222. is_inline_feed(FALSE),
  5223. origin_thread(NULL),
  5224. from_html_attribute(FALSE)
  5225. {
  5226. }
  5227. #ifdef DOM_LOAD_TV_APP
  5228. void DocumentManager::SetWhitelist(OpAutoVector<OpString>* new_whitelist)
  5229. {
  5230. OP_DELETE(whitelist);
  5231. whitelist = new_whitelist;
  5232. }
  5233. #endif
  5234. void DocumentManager::OpenURL(URL url, DocumentReferrer referrer, BOOL check_if_expired, BOOL reload, const OpenURLOptions &options)
  5235. {
  5236. activity_loading.Begin();
  5237. #ifdef DOM_LOAD_TV_APP
  5238. if (whitelist)
  5239. {
  5240. BOOL is_whitelisted = FALSE;
  5241. OpString url_name;
  5242. if (!OpStatus::IsSuccess(url.GetAttribute(URL::KUniName, url_name, false)))
  5243. return;
  5244. for (unsigned int i = 0; i < whitelist->GetCount() && !is_whitelisted; i++)
  5245. {
  5246. if (url_name.Compare(whitelist->Get(i)->CStr(), whitelist->Get(i)->Length()) == 0)
  5247. is_whitelisted = TRUE;
  5248. }
  5249. if (!is_whitelisted)
  5250. {
  5251. WindowCommander* wc = window->GetWindowCommander();
  5252. wc->GetTVAppMessageListener()->OnOpenForbiddenUrl(wc, url_name.CStr());
  5253. return;
  5254. }
  5255. }
  5256. #endif
  5257. BOOL user_initiated = options.user_initiated;
  5258. BOOL create_doc_now = options.create_doc_now;
  5259. EnteredByUser entered_by_user = options.entered_by_user;
  5260. BOOL is_walking_in_history = options.is_walking_in_history;
  5261. BOOL es_terminated = options.es_terminated;
  5262. BOOL bypass_url_access_check = options.bypass_url_access_check;
  5263. // OpenURL was called without updating current_url to the one set in the history state.
  5264. // (it is normally updated in SetLoadStat(NOT_LOADING) but it may happen SetLoadStat() was not called like e.g. when window.location is changed)
  5265. if (history_state_doc_elm && history_state_doc_elm == current_doc_elm
  5266. && referrer.url == current_url && history_state_doc_elm->GetReferrerUrl().url == current_url)
  5267. {
  5268. history_state_doc_elm->Doc()->ClearAuxUrlToHandleLoadingMessagesFor();
  5269. SetCurrentURL(history_state_doc_elm->GetUrl(), FALSE);
  5270. current_url_is_inline_feed = FALSE;
  5271. referrer = DocumentReferrer(current_url);
  5272. history_state_doc_elm = NULL;
  5273. }
  5274. FramesDocument* doc = GetCurrentDoc();
  5275. if (doc && !doc->IsContentChangeAllowed())
  5276. return;
  5277. #ifdef EXTENSION_SUPPORT
  5278. if (!parent_doc &&
  5279. window->GetType() == WIN_TYPE_GADGET &&
  5280. window->GetGadget()->IsExtension() &&
  5281. window->GetGadget()->GadgetUrlLoaded() &&
  5282. !reload &&
  5283. (!security_check_callback || !security_check_callback->m_suspended))
  5284. return; // No loading urls in the extension background process once it was loaded for the first time.
  5285. #endif // EXTENSION_SUPPORT
  5286. // Sandboxed documents are not allowed to navigate parent documents or the top level document,
  5287. // unless the top level is the sandbox document.
  5288. if (referrer.origin && referrer.origin->in_sandbox)
  5289. {
  5290. FramesDocument* sandbox_doc = doc;
  5291. if (!sandbox_doc)
  5292. sandbox_doc = GetParentDoc();
  5293. if (!sandbox_doc)
  5294. return;
  5295. while (!(sandbox_doc->GetOrigin()->security_context == referrer.origin->security_context))
  5296. {
  5297. sandbox_doc = sandbox_doc->GetParentDoc();
  5298. if (!sandbox_doc)
  5299. {
  5300. // Disallow attempt to navigate outside the sandbox.
  5301. return;
  5302. }
  5303. }
  5304. }
  5305. #ifdef ERROR_PAGE_SUPPORT
  5306. /* Before doing anything, we need to check if we're coming
  5307. * from a click-through page because the url might change
  5308. * to point to the real one. This method might mutate both
  5309. * url and referrer. This happens for:
  5310. * opera:crossnetworkwarning
  5311. * opera:site-warning
  5312. * opera:clickjackblocking
  5313. **/
  5314. do {
  5315. OP_STATUS status = HandleClickThroughUrl(url, referrer);
  5316. RaiseCondition(status);
  5317. RETURN_VOID_IF_ERROR(status);
  5318. } while(0);
  5319. #endif // ERROR_PAGE_SUPPORT
  5320. #ifdef APPLICATION_CACHE_SUPPORT
  5321. ApplicationCache *cache = g_application_cache_manager ? g_application_cache_manager->GetCacheFromContextId(url.GetContextId()) : NULL;
  5322. HTTP_Method method = static_cast<HTTP_Method>(url.GetAttribute(URL::KHTTP_Method));
  5323. if ((method != HTTP_METHOD_POST && method != HTTP_METHOD_PUT && cache && cache->IsCached(url) == FALSE) || (cache && url.GetAttribute(URL::KIsApplicationCacheForeign)))
  5324. {
  5325. /* The url is loaded from an application cache context. However, the
  5326. * url does not exit in the cache. Since this url is loaded on top level,
  5327. * the document may not actual be offline application. Thus we initiate
  5328. * the load from default cache, otherwise we'll get a load error. If this
  5329. * happens to be a offline application after all, this will be taken care
  5330. * of by GetURL() or by the parser if the document contains a manifest
  5331. * attribute.
  5332. *
  5333. * Also if the application is a foreign document, load from default cache.
  5334. *
  5335. */
  5336. OpString url_str;
  5337. OpStatus::Ignore(url.GetAttribute(URL::KUniName_With_Fragment_Username_Password_NOT_FOR_UI, url_str));
  5338. OP_ASSERT(url.GetContextId() != window->GetUrlContextId());
  5339. url = g_url_api->GetURL(url_str, window->GetUrlContextId());
  5340. }
  5341. #endif // APPLICATION_CACHE
  5342. const uni_char *hostname;
  5343. if (!window->GetWindowCommander()->GetLoadingListener()->OnAboutToLoadUrl(
  5344. window->GetWindowCommander(),
  5345. url.Name(PASSWORD_NOTHING),
  5346. GetFrame() != NULL //If we got a frame, we are an inline
  5347. ))
  5348. return; //Exit if rejected!
  5349. start_navigation_time_ms = g_op_time_info->GetRuntimeMS();
  5350. int priority;
  5351. if (GetParentDoc())
  5352. if (user_initiated)
  5353. priority = FramesDocument::LOAD_PRIORITY_FRAME_DOCUMENT_USER_INITIATED;
  5354. else
  5355. priority = FramesDocument::LOAD_PRIORITY_FRAME_DOCUMENT;
  5356. else
  5357. if (user_initiated)
  5358. priority = FramesDocument::LOAD_PRIORITY_MAIN_DOCUMENT_USER_INITIATED;
  5359. else
  5360. priority = FramesDocument::LOAD_PRIORITY_MAIN_DOCUMENT;
  5361. url.SetAttribute(URL::KHTTP_Priority, priority);
  5362. #ifdef NEARBY_ELEMENT_DETECTION
  5363. window->SetElementExpander(NULL);
  5364. #endif // NEARBY_ELEMENT_DETECTION
  5365. // URL must be constructed with a context id in privacy mode
  5366. OP_ASSERT(!window->GetPrivacyMode() || url.GetContextId());
  5367. #ifdef HTTP_CONTENT_USAGE_INDICATION
  5368. if( GetFrame() != NULL ) // This is not the main document
  5369. url.SetAttribute(URL::KHTTP_ContentUsageIndication, HTTP_UsageIndication_OtherInline);
  5370. else
  5371. url.SetAttribute(URL::KHTTP_ContentUsageIndication, HTTP_UsageIndication_MainDocument);
  5372. #endif // HTTP_CONTENT_USAGE_INDICATION
  5373. if (doc)
  5374. hostname = doc->GetHostName();
  5375. else
  5376. hostname = NULL;
  5377. #ifdef SUPPORT_VISUAL_ADBLOCK
  5378. // cache the server name so it's faster to do a lookup to check if the content blocker is enabled or not
  5379. if (doc && !parent_doc)
  5380. if (ServerName *server_name = doc->GetURL().GetServerName())
  5381. window->SetContentBlockServerName(server_name);
  5382. #endif // SUPPORT_VISUAL_ADBLOCK
  5383. BOOL pref_frames_enabled = g_pcdisplay->GetIntegerPref(PrefsCollectionDisplay::FramesEnabled, hostname);
  5384. BOOL ignore_url_request = IgnoreURLRequest(url, options.origin_thread);
  5385. CheckExpiryType pref_check_expiry = (CheckExpiryType)
  5386. g_pcnet->GetIntegerPref(is_walking_in_history
  5387. ? PrefsCollectionNetwork::CheckExpiryHistory
  5388. : PrefsCollectionNetwork::CheckExpiryLoad);
  5389. // this thing is to clear URLCameFromAddressField flag when going to a new url
  5390. // It is needed for the UI to be able to know if it should set focus back to
  5391. // address field or not when stopping transfer. (Trond)
  5392. if (!es_terminated)
  5393. GetWindow()->SetURLCameFromAddressField(FALSE);
  5394. // We set this to TRUE if we show an error page instead of the page itself.
  5395. // This is so that we can return an error status to the document listener
  5396. // even if the error page itself loads.
  5397. error_page_shown = FALSE;
  5398. // If we are opening another URL asynchronously, let it override this URL.
  5399. if (es_terminated && !url_load_on_command.IsEmpty() && !(url_load_on_command == url)
  5400. && !(url_load_on_command == current_url && url_load_on_command.RelName()))
  5401. return;
  5402. #ifdef SUPPORT_VERIZON_EXTENSIONS
  5403. url.SetAttribute( URL::KStoreAllHeaders, TRUE);
  5404. #endif //SUPPORT_VERIZON_EXTENSIONS
  5405. if (security_check_callback && security_check_callback->m_suspended && !security_check_callback->m_done)
  5406. {
  5407. /* The previous security check didn't finish and we're loading
  5408. * a new one now, so cut the previous one loose, have it ignore
  5409. * the result and start a new one.
  5410. */
  5411. security_check_callback->Invalidate();
  5412. security_check_callback = NULL;
  5413. }
  5414. if (!load_image_only && !save_image_only && !bypass_url_access_check)
  5415. {
  5416. if (!security_check_callback)
  5417. {
  5418. security_check_callback = OP_NEW(SecurityCheckCallback, (this));
  5419. if (!security_check_callback)
  5420. return;
  5421. }
  5422. OP_ASSERT(!security_check_callback->m_suspended || security_check_callback->m_done);
  5423. if (!security_check_callback->m_suspended)
  5424. {
  5425. SecCheckRes res = InitiateSecurityCheck(url, referrer);
  5426. if (res == SEC_CHECK_STARTED)
  5427. security_check_callback->PrepareForSuspending(check_if_expired, reload, options);
  5428. if (res != SEC_CHECK_ALLOWED)
  5429. return;
  5430. }
  5431. OP_ASSERT(!security_check_callback->m_suspended || security_check_callback->m_allowed);
  5432. security_check_callback->Reset();
  5433. }
  5434. else
  5435. {
  5436. OP_DELETE(security_check_callback);
  5437. security_check_callback = NULL;
  5438. }
  5439. #ifdef ON_DEMAND_PLUGIN
  5440. if (FramesDocElm *frame = GetFrame())
  5441. if (HTML_Element *frame_element = frame->GetHtmlElement())
  5442. if (frame_element->IsPluginPlaceholder())
  5443. CreatePluginPlaceholderUrl(frame->GetParentFramesDoc()->GetURL(), url);
  5444. #endif // ON_DEMAND_PLUGIN
  5445. check_expiry = check_if_expired ? pref_check_expiry : CHECK_EXPIRY_NEVER;
  5446. history_walk = is_walking_in_history && frame ? frame->GetDocManager()->GetHistoryDirection() : DM_NOT_HIST;
  5447. FramesDocument* current_doc = GetCurrentDoc();
  5448. OP_MEMORY_VAR BOOL relative_jump = !reload && !options.ignore_fragment_id && IsRelativeJump(url);
  5449. // Relative jump within the document.
  5450. // But it's not a jump if the document being opened is an inline
  5451. // webfeed in which case a generated viewer page needs to be opened
  5452. // even though the URL looks like a relative jump.
  5453. if (relative_jump && !options.is_inline_feed)
  5454. {
  5455. OP_BOOLEAN result = JumpToRelativePosition(url);
  5456. if (result == OpBoolean::IS_TRUE)
  5457. return;
  5458. }
  5459. if (window->GetOOMOccurred() && !(url == current_url))
  5460. {
  5461. UnloadCurrentDoc();
  5462. es_terminated = TRUE;
  5463. }
  5464. window->SetOOMOccurred(FALSE);
  5465. if (!es_terminated)
  5466. {
  5467. if (current_doc)
  5468. {
  5469. BOOL need_termination = current_doc->ESNeedTermination(url, reload);
  5470. if (url.Type() == URL_JAVASCRIPT)
  5471. {
  5472. OP_STATUS ret = current_doc->ConstructDOMEnvironment();
  5473. if (OpStatus::IsSuccess(ret))
  5474. if (DOM_Environment *environment = current_doc->GetDOMEnvironment())
  5475. if (environment->IsEnabled())
  5476. {
  5477. ret = current_doc->ESOpenURL(url, referrer, check_if_expired, reload, FALSE, options, entered_by_user == WasEnteredByUser, FALSE, FALSE);
  5478. if (OpStatus::IsSuccess(ret))
  5479. {
  5480. SetCurrentURL(url, FALSE);
  5481. current_url_is_inline_feed = options.is_inline_feed;
  5482. SetLoadStat(WAIT_FOR_HEADER);
  5483. // Load will be finished when the ES_Thread created by ESOpenURL
  5484. // finishes.
  5485. OP_ASSERT(current_doc->GetESScheduler() && current_doc->GetESScheduler()->HasRunnableTasks());
  5486. }
  5487. else if (ret == OpStatus::ERR)
  5488. ret = OpStatus::OK;
  5489. }
  5490. if (OpStatus::IsError(ret))
  5491. RaiseCondition(ret);
  5492. return;
  5493. }
  5494. else if (need_termination)
  5495. {
  5496. /* Let the ES scheduler finish current tasks and fire an unload event.
  5497. After that it will call this function again with es_terminated==TRUE. */
  5498. OP_STATUS ret = current_doc->ESOpenURL(url, referrer, check_if_expired, reload, GetRedirect(),
  5499. options, FALSE, FALSE, FALSE, GetUserAutoReload());
  5500. if (OpStatus::IsMemoryError(ret))
  5501. RaiseCondition(ret);
  5502. return;
  5503. }
  5504. }
  5505. }
  5506. #ifdef LIBOPERA
  5507. window->SetUserInitiated(user_initiated);
  5508. #endif
  5509. // This call is moved to after HandleHeaderLoaded is done, the information was needed by WML in a later stage.
  5510. // If this leads to any problem, contact pw@opera.com.
  5511. // window->SetURLCameFromAddressField(FALSE);
  5512. if (is_clearing)
  5513. return;
  5514. #ifdef _PRINT_SUPPORT_
  5515. if (print_preview_vd)
  5516. window->TogglePrintMode(TRUE);
  5517. #endif // _PRINT_SUPPORT_
  5518. OP_MEMORY_VAR BOOL raise_OOM_condition = FALSE;
  5519. if (user_initiated)
  5520. GetWindow()->SetHasShownUnsolicitedDownloadDialog(FALSE); // Allow a new download dialog after the user has requested a new document
  5521. URLType url_type = url.Type();
  5522. BOOL unwanted_recursive_frame_load = !user_initiated && IsRecursiveDocumentOpening(url, options.from_html_attribute);
  5523. if ((url.IsEmpty() || unwanted_recursive_frame_load) && !current_doc_elm)
  5524. {
  5525. OP_STATUS ret = CreateInitialEmptyDocument(FALSE, FALSE);
  5526. if (OpStatus::IsError(ret))
  5527. RaiseCondition(ret);
  5528. else
  5529. OP_ASSERT(current_doc_elm);
  5530. }
  5531. if (unwanted_recursive_frame_load)
  5532. return;
  5533. if (url.IsEmpty() && !create_doc_now)
  5534. {
  5535. OP_STATUS ret = HandleDocFinished();
  5536. if (OpStatus::IsError(ret))
  5537. RaiseCondition(ret);
  5538. return;
  5539. }
  5540. #ifdef _KIOSK_MANAGER_
  5541. if(url_type == URL_MAILTO && KioskManager::GetInstance()->GetNoMailLinks())
  5542. return;
  5543. #endif // _KIOSK_MANAGER_
  5544. if (url.Type() != URL_JAVASCRIPT && !current_url.IsEmpty() && !(current_url == url))
  5545. {
  5546. // N.B. Some aspects of OpenURL() rely on the state of the document manager so we can't use DocumentManager::StopLoading() here.
  5547. // It would reset the state and make OpenURL() do the wrong thing (e.g. use_history_number)
  5548. current_url.StopLoading(mh);
  5549. if (doc && request_thread_info.type == ES_THREAD_EMPTY)
  5550. doc->StopLoading(FALSE, FALSE, FALSE);
  5551. }
  5552. #if defined WEB_HANDLERS_SUPPORT || defined QUICK
  5553. const OP_BOOLEAN status = ignore_url_request
  5554. #if defined WEB_HANDLERS_SUPPORT
  5555. || skip_protocol_handler_check
  5556. #endif // WEB_HANDLERS_SUPPORT
  5557. ? OpBoolean::IS_FALSE : AttemptExecuteURLsRecognizedByOpera(url, referrer, user_initiated, entered_by_user == WasEnteredByUser);
  5558. #if defined WEB_HANDLERS_SUPPORT
  5559. skip_protocol_handler_check = FALSE;
  5560. #endif // WEB_HANDLERS_SUPPORT
  5561. if (OpStatus::IsMemoryError(status))
  5562. raise_OOM_condition = TRUE;
  5563. else if (status == OpBoolean::IS_TRUE)
  5564. return;
  5565. #endif // WEB_HANDLERS_SUPPORT || QUICK
  5566. if (g_url_api->LoadAndDisplayPermitted(url))
  5567. {
  5568. // Do not ask if offline. We will be asked again later after offline->online toggling.
  5569. BOOL is_offline = FALSE;
  5570. RaiseCondition(UpdateOfflineModeHelper(FALSE, is_offline));
  5571. window->SetState(CLICKABLE);
  5572. SetLoadStat(WAIT_FOR_HEADER);
  5573. if ((entered_by_user == WasEnteredByUser || pending_url_user_initiated)
  5574. && user_started_loading == FALSE)
  5575. {
  5576. user_started_loading = TRUE;
  5577. }
  5578. user_initiated_loading = user_initiated;
  5579. #ifdef ABSTRACT_CERTIFICATES
  5580. if (url.GetAttribute(URL::KType) == URL_HTTPS)
  5581. if (OpStatus::IsMemoryError(url.SetAttribute(URL::KCertificateRequested, TRUE)))
  5582. raise_OOM_condition = TRUE;
  5583. #endif // ABSTRACT_CERTIFICATES
  5584. SetReload(reload);
  5585. BOOL es_force_reload = url_replace_on_command;
  5586. URL tmpurl = URL(); // this is needed because of ARM compiler issue
  5587. SetUrlLoadOnCommand(tmpurl, referrer, FALSE, entered_by_user == WasEnteredByUser);
  5588. if (!save_image_only)
  5589. {
  5590. if (window->SetProgressText(url) == OpStatus::ERR_NO_MEMORY)
  5591. raise_OOM_condition = TRUE;
  5592. }
  5593. // do this check before window->StartProgressDisplay() is called !!!
  5594. BOOL update_security_state = (GetSubWinId() != -1 && (!window->IsLoading() || !current_url.IsEmpty()));
  5595. if (!(current_url == url))
  5596. SetAction(VIEWER_NOT_DEFINED);
  5597. #ifdef WEB_HANDLERS_SUPPORT
  5598. SetActionLocked(FALSE);
  5599. #endif // WEB_HANDLERS_SUPPORT
  5600. // We must call SetCurrentURL() before calling StartProgressDisplay().
  5601. SetCurrentURL(url, FALSE);
  5602. current_url_is_inline_feed = options.is_inline_feed;
  5603. DropCurrentLoadingOrigin();
  5604. if (!IsURLSuitableSecurityContext(url))
  5605. {
  5606. if (referrer.IsEmpty())
  5607. {
  5608. if (IsAboutBlankURL(url))
  5609. current_loading_origin = DocumentOrigin::MakeUniqueOrigin(url.GetContextId(), FALSE);
  5610. }
  5611. else if (referrer.origin)
  5612. {
  5613. // Inherit security from the referrer.
  5614. current_loading_origin = referrer.origin;
  5615. current_loading_origin->IncRef();
  5616. }
  5617. else
  5618. current_loading_origin = DocumentOrigin::Make(referrer.url);
  5619. if ((!referrer.IsEmpty() || IsAboutBlankURL(url)) && !current_loading_origin)
  5620. raise_OOM_condition = TRUE;
  5621. }
  5622. if (url.Type() != URL_JAVASCRIPT)
  5623. CancelRefresh();
  5624. initial_request_url = url;
  5625. #ifdef TRUST_RATING
  5626. if (!parent_doc)
  5627. {
  5628. if (entered_by_user || user_initiated)
  5629. m_active_trust_checks.Clear(); // Abandon active checks when going to a new top level user initiated URL
  5630. }
  5631. OP_STATUS status = CheckTrustRating(url);
  5632. if (status == OpStatus::ERR_NO_ACCESS)
  5633. return;
  5634. if (OpStatus::IsMemoryError(status))
  5635. raise_OOM_condition = TRUE;
  5636. #endif // TRUST_RATING
  5637. // remember referrer url
  5638. #ifdef _WML_SUPPORT_
  5639. BOOL send_referrer = reload ? ShouldSendReferrer()
  5640. : (!WMLGetContext() || WMLGetContext()->IsSet(WS_SENDREF));
  5641. SetReferrerURL(referrer, send_referrer);
  5642. if (entered_by_user == WasEnteredByUser && wml_context)
  5643. wml_context->SetStatusOn(WS_USERINIT);
  5644. #else // _WML_SUPPORT_
  5645. SetReferrerURL(referrer, TRUE);
  5646. #endif // _WML_SUPPORT_
  5647. NotifyUrlChangedIfAppropriate(url);
  5648. #ifdef OPERA_PERFORMANCE
  5649. if (user_initiated || entered_by_user == WasEnteredByUser)
  5650. urlManager->OnUserInitiatedLoad();
  5651. #endif // OPERA_PERFORMANCE
  5652. // only force the reset of security state if we are the top document
  5653. if (!save_image_only)
  5654. {
  5655. // only force the reset of security state if we are the top document
  5656. if (window->StartProgressDisplay(TRUE, !parent_doc /* bResetSecurityState */, !!parent_doc /* bSubResourcesOnly */) == OpStatus::ERR_NO_MEMORY)
  5657. raise_OOM_condition = TRUE;
  5658. if (!parent_doc)
  5659. // StartProgressDisplay won't do it if the progress bar is already visible, but it should still be done.
  5660. window->ResetSecurityStateToUnknown();
  5661. // window->StartProgressDisplay() will set SecurityState to SECURITY_STATE_UNKNOWN
  5662. if (update_security_state)
  5663. window->DocManager()->UpdateSecurityState(FALSE);
  5664. }
  5665. BOOL from_cache_ref;
  5666. if (GetSubWinId() < 0)
  5667. {
  5668. from_cache_ref = window->AlwaysLoadFromCache();
  5669. window->SetUserLoadFromCache(from_cache_ref);
  5670. }
  5671. else
  5672. from_cache_ref = window->GetUserLoadFromCache();
  5673. if (frame && window->IsURLAlreadyRequested(url) && url.Status(TRUE) == URL_LOADED)
  5674. from_cache_ref = TRUE;
  5675. BOOL if_modified_only = FALSE;
  5676. BOOL force_user_reload = FALSE;
  5677. if (!es_force_reload)
  5678. {
  5679. if_modified_only = !!url.GetAttribute(URL::KStillSameUserAgent);
  5680. #if defined(WEB_TURBO_MODE) && defined(HTTP_CONTENT_USAGE_INDICATION)
  5681. // Always perform full reload of Turbo mode images opened or saved separately
  5682. if (if_modified_only && reload_document && (load_image_only || save_image_only) &&
  5683. url.GetAttribute(URL::KUsesTurbo) &&
  5684. url.GetAttribute(URL::KHTTP_ContentUsageIndication) == HTTP_UsageIndication_MainDocument)
  5685. {
  5686. if_modified_only = FALSE;
  5687. }
  5688. #endif // WEB_TURBO_MODE && HTTP_CONTENT_USAGE_INDICATION
  5689. if (GetUserAutoReload())
  5690. {
  5691. if_modified_only = TRUE;
  5692. force_user_reload = TRUE;
  5693. }
  5694. else if (reload && current_doc && current_doc->GetURL() == url && (!current_doc->IsFrameDoc() || !pref_frames_enabled))
  5695. if_modified_only = FALSE;
  5696. }
  5697. URL_Reload_Policy reloadpolicy;
  5698. if (from_cache_ref || relative_jump || !check_if_expired)
  5699. {
  5700. if (url.GetAttribute(URL::KCachePolicy_MustRevalidate, TRUE) || force_user_reload)
  5701. reloadpolicy = URL_Reload_Conditional;
  5702. else if (url.Status(FALSE) != URL_LOADED)
  5703. reloadpolicy = URL_Reload_If_Expired;
  5704. else if (!check_if_expired && reload)
  5705. reloadpolicy = URL_Reload_Full;
  5706. else
  5707. reloadpolicy = URL_Reload_None;
  5708. }
  5709. else if (reload_document)
  5710. if (if_modified_only || conditionally_request_document)
  5711. reloadpolicy = URL_Reload_Conditional;
  5712. else
  5713. reloadpolicy = URL_Reload_Full;
  5714. else
  5715. reloadpolicy = URL_Reload_If_Expired;
  5716. if (window->GetOnlineMode() == Window::DENIED)
  5717. reloadpolicy = URL_Reload_None;
  5718. URL_LoadPolicy loadpolicy(FALSE, reloadpolicy, user_initiated || entered_by_user == WasEnteredByUser);
  5719. #ifdef SCOPE_DOCUMENT_MANAGER
  5720. if (OpScopeDocumentListener::IsEnabled())
  5721. {
  5722. OpScopeDocumentListener::AboutToLoadDocumentArgs args;
  5723. args.url = url.GetRep();
  5724. args.referrer_url = URL(referrer.url).GetRep();
  5725. args.check_if_expired = check_if_expired;
  5726. args.reload = reload;
  5727. args.options = options;
  5728. OpStatus::Ignore(OpScopeDocumentListener::OnAboutToLoadDocument(this, args));
  5729. }
  5730. #endif // SCOPE_DOCUMENT_MANAGER
  5731. if (url == current_url_reserved.GetURL())
  5732. /* Need to unset it before calling LoadDocument(), since it would
  5733. otherwise block reload. */
  5734. current_url_reserved.UnsetURL();
  5735. HTMLLoadContext* ctx_ptr = NULL;
  5736. #ifdef URL_FILTER
  5737. FramesDocument *initiating_doc = NULL;
  5738. if (options.origin_thread && options.origin_thread->GetScheduler())
  5739. initiating_doc = options.origin_thread->GetScheduler()->GetFramesDocument();
  5740. else if (parent_doc)
  5741. initiating_doc = parent_doc;
  5742. else
  5743. initiating_doc = current_doc;
  5744. DOM_Environment *dom_env = NULL;
  5745. ServerName *doc_sn = NULL;
  5746. BOOL is_widget = FALSE;
  5747. if (initiating_doc)
  5748. {
  5749. dom_env = initiating_doc->GetDOMEnvironment();
  5750. doc_sn = initiating_doc->GetURL().GetServerName();
  5751. is_widget = initiating_doc->GetWindow()->GetType() == WIN_TYPE_GADGET;
  5752. }
  5753. URLFilterDOMListenerOverride lsn_over(dom_env, NULL);
  5754. HTMLLoadContext ctx(parent_doc ? RESOURCE_SUBDOCUMENT : RESOURCE_DOCUMENT, doc_sn, &lsn_over, is_widget);
  5755. ctx_ptr = &ctx;
  5756. #endif // URL_FILTER
  5757. #ifdef _WML_SUPPORT_
  5758. CommState state = url.LoadDocument(mh, send_referrer ? referrer.url : URL(), loadpolicy, ctx_ptr);
  5759. #else // _WML_SUPPORT_
  5760. CommState state = url.LoadDocument(mh, referrer.url, loadpolicy, ctx_ptr);
  5761. #endif // _WML_SUPPORT_
  5762. if (state != COMM_REQUEST_FAILED)
  5763. {
  5764. window->SetURLAlreadyRequested(url);
  5765. if (OpStatus::IsMemoryError(current_url_reserved.SetURL(url)))
  5766. raise_OOM_condition = TRUE;
  5767. scroll_to_fragment_in_document_finished = !reload;
  5768. }
  5769. }
  5770. else if (url_type == URL_JAVASCRIPT && g_pcjs->GetIntegerPref(PrefsCollectionJS::EcmaScriptEnabled, referrer.url))
  5771. {
  5772. /* All urls loaded in frames documents are handled above, so if we get
  5773. here we either have no document (in which case we create a new one)
  5774. or we have a document that isn't a frames document (in which case
  5775. we just report an error since javascript urls can only be executed
  5776. in frames documents). */
  5777. OP_ASSERT(!current_doc);
  5778. // We have no document to execute in. Create one.
  5779. if (!current_url.IsEmpty())
  5780. /* Security check. */
  5781. if (current_url.Type() != referrer.url.Type() || !current_url.SameServer(referrer.url, URL::KCheckPort))
  5782. return;
  5783. // We must call SetCurrentURL() so that the scripts get the right referrer
  5784. SetCurrentURL(url, FALSE);
  5785. current_url_is_inline_feed = options.is_inline_feed;
  5786. SetReferrerURL(referrer); // remember referrer url
  5787. DropCurrentLoadingOrigin();
  5788. if (!referrer.IsEmpty())
  5789. {
  5790. if (referrer.origin)
  5791. {
  5792. // Inherit security from the referrer.
  5793. current_loading_origin = referrer.origin;
  5794. current_loading_origin->IncRef();
  5795. }
  5796. else
  5797. current_loading_origin = DocumentOrigin::Make(referrer.url);
  5798. if (!current_loading_origin)
  5799. raise_OOM_condition = TRUE;
  5800. }
  5801. create_doc_now = FALSE;
  5802. use_current_doc = TRUE;
  5803. if (OpStatus::IsMemoryError(SetCurrentDoc(check_if_expired, FALSE, FALSE, user_initiated)))
  5804. raise_OOM_condition = TRUE;
  5805. use_current_doc = FALSE;
  5806. current_doc = GetCurrentDoc();
  5807. /* No security checking is necessary here since this is a new, empty
  5808. document that we just created. In fact, it would almost certainly fail
  5809. since the url of the document is the javascript url, not an url that is
  5810. compatible with the origin url. */
  5811. OP_STATUS ret = current_doc->ESOpenJavascriptURL(url, TRUE, FALSE, reload, FALSE, NULL, entered_by_user == WasEnteredByUser, FALSE, FALSE);
  5812. if (OpStatus::IsMemoryError(ret))
  5813. raise_OOM_condition = TRUE;
  5814. else if (OpStatus::IsError(ret))
  5815. return;
  5816. }
  5817. else if (url_type == URL_MAILTO)
  5818. {
  5819. if (!ignore_url_request)
  5820. {
  5821. OpString8 servername;
  5822. BOOL mailto_from_form = !!url.GetAttribute(URL::KHTTPIsFormsRequest);
  5823. if (mailto_from_form)
  5824. {
  5825. if (current_url.GetServerName())
  5826. servername.Set(current_url.GetServerName()->Name());
  5827. }
  5828. window->GenericMailToAction(url, options.called_externally, mailto_from_form, servername);
  5829. }
  5830. }
  5831. #if defined(M2_SUPPORT) && defined(IRC_SUPPORT)
  5832. else if (url_type == URL_IRC || url_type == URL_CHAT_TRANSFER)
  5833. {
  5834. if (!ignore_url_request && g_m2_engine && OpStatus::IsMemoryError(g_m2_engine->MailCommand(url)))
  5835. raise_OOM_condition = TRUE;
  5836. else
  5837. {
  5838. if (url_type == URL_CHAT_TRANSFER && window->GetType() != WIN_TYPE_IM_VIEW)
  5839. window->Close();
  5840. return;
  5841. }
  5842. }
  5843. #endif // M2_SUPPORT && IRC_SUPPORT
  5844. #if !defined(NO_FTP_SUPPORT) || defined(GOPHER_SUPPORT) || defined(WAIS_SUPPORT)
  5845. else if (url_type == URL_FTP || url_type == URL_Gopher || url_type == URL_WAIS)
  5846. {
  5847. if (!ignore_url_request)
  5848. {
  5849. if (entered_by_user != WasEnteredByUser && !user_initiated)
  5850. {
  5851. #ifdef OPERA_CONSOLE
  5852. PostURLErrorToConsole(url, Str::SI_ERR_REQUIRES_PROXY_SERVER);
  5853. #endif // OPERA_CONSOLE
  5854. }
  5855. else
  5856. window->HandleLoadingFailed(Str::SI_ERR_REQUIRES_PROXY_SERVER, url);
  5857. }
  5858. }
  5859. #endif // !NO_FTP_SUPPORT || GOPHER_SUPPORT || WAIS_SUPPORT
  5860. #ifdef IMODE_EXTENSIONS
  5861. else if (url_type == URL_TEL)
  5862. {
  5863. OpString tel_str;
  5864. BOOL bHandled = FALSE;
  5865. if (OpStatus::IsMemoryError(url.GetAttribute(URL::KUniName_For_Tel, tel_str, FALSE)))
  5866. raise_OOM_condition = TRUE;
  5867. else
  5868. bHandled = window->GetWindowCommander()->GetDocumentListener()->OnUnknownProtocol(window->GetWindowCommander(), tel_str.CStr());
  5869. if (!bHandled)
  5870. {
  5871. SetCurrentURL(url, FALSE);
  5872. current_url_is_inline_feed = options.is_inline_feed;
  5873. HandleLoadingFailed(url.Id(), DH_ERRSTR(SI,ERR_UNKNOWN_ADDRESS_TYPE));
  5874. }
  5875. }
  5876. #endif // IMODE_EXTENSIONS
  5877. else
  5878. {
  5879. BOOL bHandled = FALSE;
  5880. WindowCommander* wic = window->GetWindowCommander();
  5881. // Need to copy string, since UniName (and cousins) use tempbuffers.
  5882. OpString url_str;
  5883. if (OpStatus::IsMemoryError(url.GetAttribute(
  5884. URL::KUniName_With_Fragment_Username_Password_Hidden_Escaped,
  5885. url_str)))
  5886. raise_OOM_condition = TRUE;
  5887. else
  5888. bHandled = wic->GetDocumentListener()->OnUnknownProtocol(wic, url_str.CStr());
  5889. #if defined MSWIN || defined _UNIX_DESKTOP_ || defined _MACINTOSH_
  5890. #ifdef QUICK
  5891. bHandled = Application::HandleExternalURLProtocol(url);
  5892. #endif // QUICK
  5893. #endif // MSWIN || UNIX_DESKTOP || _MACINTOSH_
  5894. if (!bHandled && !create_doc_now)
  5895. {
  5896. if (!ignore_url_request)
  5897. {
  5898. if (entered_by_user != WasEnteredByUser && !user_initiated)
  5899. {
  5900. #ifdef OPERA_CONSOLE
  5901. PostURLErrorToConsole(url, Str::SI_ERR_UNKNOWN_ADDRESS_TYPE);
  5902. #endif // OPERA_CONSOLE
  5903. }
  5904. else
  5905. {
  5906. SetCurrentURL(url, FALSE);
  5907. current_url_is_inline_feed = options.is_inline_feed;
  5908. HandleLoadingFailed(url.Id(), DH_ERRSTR(SI,ERR_UNKNOWN_ADDRESS_TYPE));
  5909. }
  5910. }
  5911. }
  5912. }
  5913. if (create_doc_now)
  5914. {
  5915. use_current_doc = TRUE;
  5916. SetCurrentURL(url, FALSE);
  5917. current_url_is_inline_feed = options.is_inline_feed;
  5918. SetReferrerURL(referrer, ShouldSendReferrer());
  5919. if (OpStatus::IsMemoryError(SetCurrentDoc(check_if_expired, FALSE, FALSE, user_initiated)))
  5920. raise_OOM_condition = TRUE;
  5921. else
  5922. current_doc_elm->SetIsPreCreated(TRUE);
  5923. use_current_doc = FALSE;
  5924. }
  5925. if (raise_OOM_condition)
  5926. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  5927. }
  5928. DocumentReferrer::DocumentReferrer(FramesDocument* doc)
  5929. : url(doc->GetSecurityContext()),
  5930. origin(doc->GetMutableOrigin())
  5931. {
  5932. origin->IncRef();
  5933. }
  5934. DocumentReferrer::DocumentReferrer(DocumentOrigin* ref_origin)
  5935. : url(ref_origin->security_context),
  5936. origin(ref_origin)
  5937. {
  5938. origin->IncRef();
  5939. }
  5940. DocumentReferrer::DocumentReferrer(const DocumentReferrer& other)
  5941. : url(other.url),
  5942. origin(other.origin)
  5943. {
  5944. if (origin)
  5945. origin->IncRef();
  5946. }
  5947. DocumentReferrer& DocumentReferrer::operator=(const DocumentReferrer& other)
  5948. {
  5949. url = other.url;
  5950. if (other.origin)
  5951. other.origin->IncRef();
  5952. if (origin)
  5953. origin->DecRef();
  5954. origin = other.origin;
  5955. return *this;
  5956. }
  5957. DocumentReferrer::~DocumentReferrer()
  5958. {
  5959. if (origin)
  5960. origin->DecRefInternal();
  5961. }
  5962. void DocumentManager::OpenURL(URL& url, const DocumentReferrer& referrer, BOOL check_if_expired, BOOL reload, BOOL user_initiated, BOOL create_doc_now, EnteredByUser entered_by_user, BOOL is_walking_in_history, BOOL es_terminated, BOOL called_externally, BOOL bypass_url_access_check)
  5963. {
  5964. OpenURLOptions options;
  5965. options.user_initiated = user_initiated;
  5966. options.create_doc_now = create_doc_now;
  5967. options.entered_by_user = entered_by_user;
  5968. options.is_walking_in_history = is_walking_in_history;
  5969. options.es_terminated = es_terminated;
  5970. options.called_externally = called_externally;
  5971. options.bypass_url_access_check = bypass_url_access_check;
  5972. OpenURL(url, referrer, check_if_expired, reload, options);
  5973. }
  5974. void
  5975. DocumentManager::OpenImageURL(URL url, const DocumentReferrer& referrer, BOOL save, BOOL new_page, BOOL in_background)
  5976. {
  5977. if (url.Type() == URL_JAVASCRIPT || (url.GetAttribute(URL::KHeaderLoaded) && !url.GetAttribute(URL::KIsImage,TRUE)))
  5978. return;
  5979. DocumentManager *docman;
  5980. if (new_page)
  5981. {
  5982. BOOL3 new_window = YES;
  5983. BOOL3 open_in_background = in_background ? YES : MAYBE;
  5984. Window *window = g_windowManager->GetAWindow(TRUE, new_window, open_in_background);
  5985. if (!window)
  5986. return;
  5987. docman = window->DocManager();
  5988. }
  5989. else
  5990. {
  5991. docman = this;
  5992. if (FramesDocument *doc = GetCurrentDoc())
  5993. if (ES_ThreadScheduler *scheduler = doc->GetESScheduler())
  5994. {
  5995. scheduler->RemoveThreads(TRUE);
  5996. OpStatus::Ignore(scheduler->Activate());
  5997. }
  5998. }
  5999. if (save)
  6000. {
  6001. docman->save_image_only = TRUE;
  6002. docman->SetActionFlag(ViewActionFlag::SAVE_AS);
  6003. }
  6004. else
  6005. {
  6006. docman->load_image_only = TRUE;
  6007. }
  6008. OpenURLOptions options;
  6009. options.user_initiated = TRUE;
  6010. options.es_terminated = TRUE;
  6011. options.ignore_fragment_id = save;
  6012. BOOL img_reload = FALSE;
  6013. #ifdef WEB_TURBO_MODE
  6014. if (url.GetAttribute(URL::KUsesTurbo) && url.GetAttribute(URL::KTurboCompressed))
  6015. img_reload = TRUE;
  6016. #endif // WEB_TURBO_MODE
  6017. docman->OpenURL(url, referrer, TRUE, img_reload, options);
  6018. }
  6019. void
  6020. DocumentManager::SetUrlLoadOnCommand(const URL& url, const DocumentReferrer& ref_url, BOOL replace_document/* = FALSE*/, BOOL was_user_initiated/* = FALSE*/, ES_Thread *origin_thread/* = NULL*/)
  6021. {
  6022. pending_url_user_initiated = was_user_initiated;
  6023. // Workaround for links of the type <a href="#rel" onclick="document.form[0].submit()">
  6024. // where the "#rel" URL will otherwise override the form submit because it is
  6025. // triggered later. This code simply makes us ignore the "#rel" URL in that case.
  6026. if (!url_load_on_command.IsEmpty() && IsRelativeJump(url))
  6027. return;
  6028. if (IgnoreURLRequest(url))
  6029. return;
  6030. url_load_on_command = url;
  6031. url_replace_on_command = replace_document;
  6032. referrer_url = ref_url;
  6033. }
  6034. void DocumentManager::SetApplication(const uni_char *str)
  6035. {
  6036. if (!current_application)
  6037. current_application = OP_NEWA(uni_char, 256);
  6038. if (current_application)
  6039. {
  6040. if (str && *str)
  6041. {
  6042. uni_strncpy(current_application, str, 255);
  6043. current_application[255] = 0;
  6044. }
  6045. else
  6046. current_application[0] = 0;
  6047. }
  6048. }
  6049. BOOL DocumentManager::IsCurrentDocLoaded(BOOL inlines_loaded)
  6050. {
  6051. switch (GetLoadStatus())
  6052. {
  6053. default:
  6054. return FALSE;
  6055. case NOT_LOADING:
  6056. case DOC_CREATED:
  6057. if (FramesDocument* doc = GetCurrentDoc())
  6058. return doc->IsLoaded(inlines_loaded);
  6059. else
  6060. return TRUE;
  6061. }
  6062. }
  6063. void DocumentManager::ResetStateFlags()
  6064. {
  6065. BOOL was_reloaded_previously = GetReload();
  6066. BOOL were_inlines_reloaded_previously = GetReloadInlines();
  6067. BOOL were_inlines_requested_conditionally_previously = GetConditionallyRequestInlines();
  6068. SetUserAutoReload(FALSE);
  6069. SetReload(FALSE);
  6070. SetRedirect(FALSE);
  6071. was_reloaded = was_reloaded_previously;
  6072. were_inlines_reloaded = were_inlines_reloaded_previously;
  6073. were_inlines_requested_conditionally = were_inlines_requested_conditionally_previously;
  6074. SetReplace(FALSE);
  6075. SetUseHistoryNumber(-1);
  6076. SetAction(VIEWER_NOT_DEFINED);
  6077. load_image_only = FALSE;
  6078. save_image_only = FALSE;
  6079. use_current_doc = FALSE;
  6080. initial_request_url = URL();
  6081. conditionally_request_document = FALSE;
  6082. conditionally_request_inlines = TRUE;
  6083. }
  6084. void DocumentManager::StopLoading(BOOL format, BOOL force_end_progress/*=FALSE*/, BOOL abort/*=FALSE*/)
  6085. {
  6086. #ifdef _PRINT_SUPPORT_
  6087. if (print_preview_vd)
  6088. return;
  6089. #endif // _PRINT_SUPPORT_
  6090. #ifdef NEARBY_ELEMENT_DETECTION
  6091. window->SetElementExpander(NULL);
  6092. #endif // NEARBY_ELEMENT_DETECTION
  6093. g_url_api->SetPauseStartLoading(TRUE);
  6094. ResetStateFlags();
  6095. URLStatus current_url_stat;
  6096. if (!current_url.IsEmpty())
  6097. {
  6098. current_url_stat = current_url.Status(TRUE);
  6099. current_url.StopLoading(mh);
  6100. }
  6101. else
  6102. current_url_stat = URL_UNLOADED;
  6103. if (FramesDocument* doc = GetCurrentDoc())
  6104. {
  6105. current_doc_elm->SetIsPreCreated(FALSE);
  6106. URL old_url = doc->GetURL();
  6107. // Stop as much as possible of the document loading. Keep
  6108. // plugins streams around in case we get a 204 response
  6109. // (CORE-8121, CORE-22650).
  6110. // OOM7: Ignore failure - writing to cache isn't critical.
  6111. // Raising condition can lead to repeated calls of this function.
  6112. OpStatus::Ignore(doc->StopLoading(format, abort, abort));
  6113. // if the loading is aborted or failed (and this is the top document) we want the failed URL in the address field
  6114. // so we set the current_url to URL() so that OnUrlChanged() wont be called.
  6115. if (!GetFrame() && current_url_stat == URL_LOADING_FAILURE || current_url_stat == URL_LOADING_ABORTED)
  6116. SetCurrentURL(URL(), FALSE);
  6117. else if (!(current_url == old_url))
  6118. SetCurrentURL(old_url, FALSE);
  6119. if (GetParentDoc() == NULL) // only for the top document
  6120. {
  6121. window->ResetSecurityStateToUnknown();
  6122. }
  6123. /* A child doc manager should not update the security status of the window if a parent doc
  6124. * manager is waiting for some url to load or about to switch documents. This happens, for
  6125. * instance, when StopLoading is called on a doc manager in the middle of the tree instead
  6126. * of the top-level doc manager.
  6127. * A parent doc manager will update the security status when it finished loading or the
  6128. * load is aborted, so doing it on the children also is wasteful and can lead to the state
  6129. * to be updated wrongfully (e.g. CORE-24298). */
  6130. BOOL update_security_status = TRUE;
  6131. for (FramesDocument* frames_doc = GetParentDoc(); frames_doc; frames_doc = frames_doc->GetDocManager()->GetParentDoc())
  6132. {
  6133. if (frames_doc->GetDocManager()->GetLoadStatus() != NOT_LOADING &&
  6134. frames_doc->GetDocManager()->GetLoadStatus() != WAIT_MULTIPART_RELOAD)
  6135. {
  6136. update_security_status = FALSE;
  6137. break;
  6138. }
  6139. }
  6140. if (update_security_status)
  6141. window->DocManager()->UpdateSecurityState(FALSE);
  6142. }
  6143. else
  6144. SetCurrentURL(URL(), FALSE);
  6145. scroll_to_fragment_in_document_finished = FALSE;
  6146. SetLoadStat(NOT_LOADING);
  6147. /* Robustness call in case VisualDevice doesn't notify that it has
  6148. * been unlocked. */
  6149. CheckOnNewPageReady();
  6150. g_url_api->SetPauseStartLoading(FALSE);
  6151. // If this is the last document in the currently loading tree then
  6152. // call EndProgressDisplay to unlock the painter and trigger a paint. If
  6153. // this on the other hand is while we're undisplaying, then the tree
  6154. // is in a state of flux and calling EndProgressDisplay could result
  6155. // in unwanted unlocking and paints.
  6156. BOOL is_undisplaying = FALSE;
  6157. for (FramesDocument* doc = GetParentDoc(); doc; doc = doc->GetParentDoc())
  6158. {
  6159. if (doc->IsUndisplaying())
  6160. {
  6161. is_undisplaying = TRUE;
  6162. break;
  6163. }
  6164. }
  6165. if (!is_undisplaying)
  6166. EndProgressDisplay(force_end_progress);
  6167. if (es_pending_unload)
  6168. OpStatus::Ignore(ESCancelPendingUnload());
  6169. }
  6170. void DocumentManager::LoadPendingUrl(URL_ID url_id, BOOL user_initiated)
  6171. {
  6172. if (is_clearing)
  6173. return;
  6174. if (url_load_on_command.Id(TRUE) == url_id)
  6175. {
  6176. URL url = url_load_on_command;
  6177. // Clear url; we don't want to trigger this twice
  6178. url_load_on_command = URL();
  6179. if (url_replace_on_command)
  6180. SetReplace(TRUE);
  6181. // ("On SHARP branch we always use ref_url = current_url")
  6182. DocumentReferrer ref_url = referrer_url;
  6183. if (ref_url.IsEmpty())
  6184. ref_url = DocumentReferrer(current_url);
  6185. // To avoid reloading internal links
  6186. BOOL check_if_expired = TRUE;
  6187. if ((ref_url.url == url) && url.RelName())
  6188. check_if_expired = FALSE;
  6189. OpenURL(url, ref_url, check_if_expired, url_replace_on_command, user_initiated);
  6190. }
  6191. }
  6192. OP_BOOLEAN DocumentManager::LoadAllImages()
  6193. {
  6194. #ifdef _PRINT_SUPPORT_
  6195. if (print_preview_vd)
  6196. return OpBoolean::IS_FALSE;
  6197. #endif // _PRINT_SUPPORT_
  6198. if (FramesDocument* doc = GetCurrentDoc())
  6199. {
  6200. BOOL is_reloading = GetReload();
  6201. if (!is_reloading)
  6202. SetReload(TRUE);
  6203. if (!window->ShowImages())
  6204. window->SetImagesSetting(FIGS_SHOW);
  6205. doc->LoadAllImages(FALSE);
  6206. if (!is_reloading)
  6207. SetReload(FALSE);
  6208. }
  6209. return OpBoolean::IS_FALSE;
  6210. }
  6211. void DocumentManager::Reload(EnteredByUser entered_by_user, BOOL conditionally_request_document, BOOL conditionally_request_inlines, BOOL is_user_auto_reload)
  6212. {
  6213. if (!GetWindow()->HasFeature(WIN_FEATURE_RELOADABLE)
  6214. #ifdef ERROR_PAGE_SUPPORT
  6215. || (current_url.Type() == URL_OPERA && current_url.GetAttribute(URL::KIsClickThroughPage)) // opera:site-warning and opera:crossnetworkwarning are not refreshable else they just turn into an error page
  6216. #endif // ERROR_PAGE_SUPPORT
  6217. )
  6218. return;
  6219. #ifdef GADGET_SUPPORT
  6220. if (GetWindow()->GetGadget())
  6221. GetWindow()->GetGadget()->Reload();
  6222. #endif // GADGET_SUPPORT
  6223. if (is_clearing)
  6224. return;
  6225. #ifdef _PRINT_SUPPORT_
  6226. if (print_preview_vd)
  6227. window->TogglePrintMode(TRUE);
  6228. #endif // _PRINT_SUPPORT_
  6229. // Observable from JavaScript
  6230. //OK to ignore the OP_STATUS return value, empty strings
  6231. OpStatus::Ignore(window->SetMessage(UNI_L("")));
  6232. OpStatus::Ignore(window->SetDefaultMessage(UNI_L("")));
  6233. // 1st bool -> parse ahead outstanding data.
  6234. // 2nd bool -> signal to remove progress bar.
  6235. // 3rd bool -> put doc in aborted state, also kills plugin streams.
  6236. StopLoading(FALSE, FALSE, TRUE);
  6237. if (FramesDocument* doc = GetCurrentDoc())
  6238. {
  6239. /* Clear the flag since it stops being true. Alternatively we could
  6240. just not reload since we don't have the content the current document
  6241. was actually parsed from (and won't get it by reloading the URL,) but
  6242. that is probably less useful. */
  6243. current_doc_elm->SetScriptGeneratedDocument(FALSE);
  6244. BOOL remove_frames = doc->IsFrameDoc() && !g_pcdisplay->GetIntegerPref(PrefsCollectionDisplay::FramesEnabled);
  6245. SetUserAutoReload(is_user_auto_reload);
  6246. SetReload(TRUE);
  6247. SetReloadFlags(TRUE, conditionally_request_document, TRUE, conditionally_request_inlines);
  6248. DocumentReferrer ref_url = doc->GetRefURL();
  6249. URL doc_url = current_doc_elm->GetUrl();
  6250. OpenURLOptions options;
  6251. options.user_initiated = TRUE;
  6252. options.create_doc_now = remove_frames; // Why?
  6253. options.entered_by_user = entered_by_user;
  6254. #ifdef WEB_TURBO_MODE
  6255. if (window->GetTurboMode() != !!doc_url.GetAttribute(URL::KUsesTurbo))
  6256. {
  6257. URL_CONTEXT_ID ctx = window->GetTurboMode() ? g_windowManager->GetTurboModeContextId() : 0;
  6258. const OpStringC8 url_str = doc_url.GetAttribute(URL::KName_With_Fragment_Username_Password_NOT_FOR_UI, URL::KNoRedirect);
  6259. doc_url = g_url_api->GetURL(url_str.CStr(),ctx);
  6260. SetUseHistoryNumber(CurrentDocListElm()->Number());
  6261. }
  6262. #endif // WEB_TURBO_MODE
  6263. OpenURL(doc_url, DocumentReferrer(ref_url), TRUE /*check_if_expired */, TRUE /*reload*/, options);
  6264. }
  6265. }
  6266. BOOL DocumentManager::ShouldSendReferrer()
  6267. {
  6268. return current_doc_elm ? current_doc_elm->ShouldSendReferrer() : send_to_server;
  6269. }
  6270. void DocumentManager::CheckHistory(int decrement, int& minhist, int& maxhist)
  6271. {
  6272. DocListElm* delm = FirstDocListElm();
  6273. while (delm)
  6274. {
  6275. int new_dec = decrement;
  6276. if (delm->Number() > maxhist + 1)
  6277. new_dec += delm->Number() - maxhist - 1;
  6278. if (new_dec)
  6279. delm->SetNumber(delm->Number() - new_dec);
  6280. if (delm->Number() < minhist)
  6281. minhist = delm->Number();
  6282. if (delm->Number() > maxhist)
  6283. maxhist = delm->Number();
  6284. delm->Doc()->CheckHistory(new_dec, minhist, maxhist);
  6285. delm = delm->Suc();
  6286. }
  6287. }
  6288. #ifdef _PRINT_SUPPORT_
  6289. OP_STATUS DocumentManager::CreatePrintDoc(BOOL preview)
  6290. {
  6291. OP_NEW_DBG("DocumentManager::CreatePrintDoc", "async_print");
  6292. FramesDocument* frames_doc = GetCurrentDoc();
  6293. FramesDocument* new_doc = NULL;
  6294. if (frames_doc)
  6295. {
  6296. PrinterInfo* printer_info = window->GetPrinterInfo(preview);
  6297. PrintDevice* pd = printer_info->GetPrintDevice();
  6298. DM_PrintType frames_print_type = window->GetFramesPrintType();
  6299. if (frames_doc->IsFrameDoc())
  6300. {
  6301. if (frames_print_type == PRINT_ACTIVE_FRAME)
  6302. {
  6303. DocumentManager* active_doc_man = frames_doc->GetActiveDocManager();
  6304. if (active_doc_man && active_doc_man->GetCurrentDoc())
  6305. frames_doc = active_doc_man->GetCurrentDoc();
  6306. else
  6307. {
  6308. frames_print_type = PRINT_ALL_FRAMES;
  6309. if (window->SetFramesPrintType(PRINT_ALL_FRAMES, FALSE) == OpStatus::ERR_NO_MEMORY)
  6310. return OpStatus::ERR_NO_MEMORY;
  6311. }
  6312. }
  6313. }
  6314. if (!preview && print_preview_doc)
  6315. {
  6316. print_doc = print_preview_doc;
  6317. GetWindow()->SetPrinting(FALSE);
  6318. GetWindow()->GetMessageHandler()->PostMessage(DOC_PRINT_FORMATTED, 0, 0);
  6319. }
  6320. else
  6321. {
  6322. new_doc = OP_NEW(FramesDocument, (this, frames_doc->GetURL(), frames_doc->GetMutableOrigin(), -1));
  6323. if (preview)
  6324. print_preview_doc = new_doc;
  6325. else
  6326. print_doc = new_doc;
  6327. if (new_doc)
  6328. {
  6329. OP_DBG(("SetFormattingPrintDoc(TRUE)"));
  6330. GetWindow()->SetFormattingPrintDoc(TRUE);
  6331. if (new_doc->CreatePrintLayout(pd, frames_doc,
  6332. pd->GetRenderingViewWidth(), pd->GetRenderingViewHeight(),
  6333. frames_print_type != PRINT_AS_SCREEN,
  6334. preview) == OpStatus::ERR_NO_MEMORY)
  6335. {
  6336. GetWindow()->SetFormattingPrintDoc(FALSE);
  6337. OP_DELETE(new_doc);
  6338. if (preview)
  6339. print_preview_doc = NULL;
  6340. else
  6341. print_doc = NULL;
  6342. return OpStatus::ERR_NO_MEMORY;
  6343. }
  6344. if (frames_doc->IsCurrentDoc())
  6345. new_doc->SetAsCurrentDoc(TRUE);
  6346. }
  6347. else
  6348. return OpStatus::ERR_NO_MEMORY;
  6349. }
  6350. }
  6351. return OpStatus::OK;
  6352. }
  6353. OP_STATUS DocumentManager::UpdatePrintPreview()
  6354. {
  6355. if (print_preview_vd)
  6356. {
  6357. FramesDocument* frames_doc = GetCurrentDoc();
  6358. if (frames_doc)
  6359. frames_doc->DeletePrintCopy();
  6360. OP_DELETE(print_preview_doc);
  6361. print_preview_doc = NULL;
  6362. if (CreatePrintDoc(TRUE) == OpStatus::ERR_NO_MEMORY)
  6363. return OpStatus::ERR_NO_MEMORY;
  6364. else
  6365. print_preview_vd->UpdateAll();
  6366. }
  6367. return OpStatus::OK;
  6368. }
  6369. OP_BOOLEAN DocumentManager::SetPrintMode(BOOL on, FramesDocElm* copy_fde, BOOL preview)
  6370. {
  6371. if (on)
  6372. {
  6373. FramesDocument* doc = (copy_fde) ? copy_fde->GetCurrentDoc() : GetCurrentDoc();
  6374. if (current_doc_elm)
  6375. StoreViewport(current_doc_elm);
  6376. if (doc && (doc->IsLoaded() /*|| GetWindow()->GetType() == WIN_TYPE_IM_VIEW*/))
  6377. {
  6378. PrinterInfo* printer_info = window->GetPrinterInfo(preview);
  6379. PrintDevice* pd = printer_info->GetPrintDevice();
  6380. DM_PrintType frames_print_type = window->GetFramesPrintType();
  6381. VisualDevice *vd = NULL;
  6382. FramesDocument *new_doc = NULL;
  6383. if (copy_fde)
  6384. {
  6385. DocumentManager* top_doc_man = GetWindow()->DocManager();
  6386. if (preview)
  6387. {
  6388. vd = copy_fde->GetVisualDevice();
  6389. if (vd->CreatePrintPreviewVD(print_preview_vd, pd) == OpStatus::ERR_NO_MEMORY)
  6390. {
  6391. //print_preview_vd = NULL;
  6392. return OpStatus::ERR_NO_MEMORY;
  6393. }
  6394. else
  6395. {
  6396. print_preview_vd->SetDocumentManager(this);
  6397. // hide original frame
  6398. vd->Hide();
  6399. vd = print_preview_vd;
  6400. print_preview_vd->GetView()->SetVisibility(TRUE);
  6401. print_preview_vd->SetFocus(FOCUS_REASON_OTHER);
  6402. }
  6403. }
  6404. else
  6405. vd = top_doc_man->GetPrintPreviewVD();
  6406. if (vd)
  6407. {
  6408. if (preview)
  6409. OP_ASSERT(print_preview_vd == vd);
  6410. else
  6411. {
  6412. print_vd = vd;
  6413. OP_ASSERT(print_vd == top_doc_man->GetPrintPreviewVD());
  6414. }
  6415. new_doc = OP_NEW(FramesDocument, (this, doc->GetURL(), doc->GetMutableOrigin(), copy_fde->GetSubWinId()));
  6416. if (!new_doc)
  6417. {
  6418. if (preview)
  6419. {
  6420. OP_DELETE(print_preview_vd);
  6421. print_preview_vd = NULL;
  6422. }
  6423. return OpStatus::ERR_NO_MEMORY;
  6424. }
  6425. if (preview)
  6426. print_preview_doc = new_doc;
  6427. else
  6428. print_doc = new_doc;
  6429. if (new_doc->CreatePrintLayout(pd, doc, frame->GetWidth(), frame->GetHeight(), frames_print_type != PRINT_AS_SCREEN && !frame->IsInlineFrame(), preview) == OpStatus::ERR_NO_MEMORY)
  6430. {
  6431. OP_DELETE(new_doc);
  6432. if (preview)
  6433. {
  6434. OP_ASSERT(print_preview_doc == new_doc);
  6435. print_preview_doc = NULL;
  6436. OP_DELETE(print_preview_vd);
  6437. print_preview_vd = NULL;
  6438. }
  6439. else
  6440. {
  6441. OP_ASSERT(print_doc == new_doc);
  6442. print_doc = NULL;
  6443. // The VisualDevice is the top-most
  6444. // VisualDevice. I assume someone else
  6445. // takes care of it
  6446. print_vd = NULL;
  6447. }
  6448. return OpStatus::ERR_NO_MEMORY;
  6449. }
  6450. if (doc->IsCurrentDoc())
  6451. new_doc->SetAsCurrentDoc(TRUE);
  6452. }
  6453. }
  6454. else
  6455. {
  6456. BOOL set_focus_on_preview_doc = FALSE;
  6457. if (preview) //window->GetPreviewMode())
  6458. {
  6459. if (vis_dev->CreatePrintPreviewVD(print_preview_vd, pd) == OpStatus::ERR_NO_MEMORY)
  6460. {
  6461. //print_preview_vd = NULL;
  6462. return OpStatus::ERR_NO_MEMORY;
  6463. }
  6464. else
  6465. {
  6466. print_preview_vd->SetDocumentManager(this);
  6467. vd = print_preview_vd;
  6468. vis_dev->Hide();
  6469. print_preview_vd->GetView()->SetVisibility(TRUE);
  6470. // Can't set focus until we have a document below
  6471. set_focus_on_preview_doc = TRUE;
  6472. }
  6473. }
  6474. else
  6475. {
  6476. if (!pd)
  6477. return OpBoolean::IS_FALSE; // No PrintDevice -> No printing
  6478. vd = pd; // print_preview_vd = pd;
  6479. print_vd = vd;
  6480. }
  6481. OP_ASSERT(vd);
  6482. OP_ASSERT(!preview || print_preview_vd);
  6483. OP_ASSERT(preview || print_vd);
  6484. // This will also hide all children documents (setting visible to FALSE for their VisualDevices)
  6485. if (CreatePrintDoc(preview) == OpStatus::ERR_NO_MEMORY)
  6486. {
  6487. OP_DELETE(print_preview_vd);
  6488. print_preview_vd = NULL;
  6489. print_vd = NULL;
  6490. return OpStatus::ERR_NO_MEMORY; //rg memfix
  6491. }
  6492. if (set_focus_on_preview_doc)
  6493. {
  6494. print_preview_vd->SetFocus(FOCUS_REASON_OTHER);
  6495. }
  6496. }
  6497. return OpBoolean::IS_TRUE;
  6498. }
  6499. else
  6500. return OpBoolean::IS_FALSE;
  6501. }
  6502. else
  6503. {
  6504. FramesDocument* frames_doc = GetCurrentDoc();
  6505. if (frames_doc && (!print_preview_doc || !print_doc))
  6506. frames_doc->DeletePrintCopy();
  6507. if (preview)
  6508. {
  6509. if (print_doc != print_preview_doc)
  6510. OP_DELETE(print_preview_doc);
  6511. print_preview_doc = NULL;
  6512. }
  6513. else
  6514. {
  6515. if (print_doc != print_preview_doc)
  6516. OP_DELETE(print_doc);
  6517. print_doc = NULL;
  6518. }
  6519. //if (!GetFrame())
  6520. {
  6521. BOOL restore_real_vd = FALSE;
  6522. if (preview && print_preview_vd)
  6523. {
  6524. OP_DELETE(print_preview_vd);
  6525. print_preview_vd = NULL;
  6526. restore_real_vd = !is_clearing;
  6527. }
  6528. else if (!preview && print_vd)
  6529. {
  6530. print_vd = NULL;
  6531. restore_real_vd = !is_clearing;
  6532. }
  6533. if (restore_real_vd)
  6534. {
  6535. vis_dev->Show(NULL);
  6536. // Need to make all the hidden children frames visible as well.
  6537. // Maybe this could be done in a better way.
  6538. DocumentTreeIterator iter(this);
  6539. iter.SetIncludeEmpty();
  6540. while (iter.Next())
  6541. {
  6542. DocumentManager* child_docman = iter.GetDocumentManager();
  6543. CoreView* parent_view = NULL;
  6544. if (child_docman->parent_doc)
  6545. {
  6546. DocumentManager* its_parent = child_docman->parent_doc->GetDocManager();
  6547. parent_view = its_parent->GetVisualDevice()->GetView();
  6548. }
  6549. child_docman->vis_dev->Show(parent_view);
  6550. }
  6551. vis_dev->SetFocus(FOCUS_REASON_OTHER);
  6552. }
  6553. }
  6554. if (!is_clearing)
  6555. if (frames_doc)
  6556. {
  6557. if (current_doc_elm->GetLastScale() != GetWindow()->GetScale())
  6558. SetScale(GetWindow()->GetScale());
  6559. else
  6560. {
  6561. frames_doc->RecalculateScrollbars();
  6562. frames_doc->RecalculateLayoutViewSize(TRUE);
  6563. }
  6564. }
  6565. if (pending_refresh_id)
  6566. {
  6567. Refresh(pending_refresh_id);
  6568. pending_refresh_id = 0;
  6569. }
  6570. return OpBoolean::IS_TRUE;
  6571. }
  6572. }
  6573. #endif // _PRINT_SUPPORT_
  6574. void DocumentManager::SetScale(int scale)
  6575. {
  6576. if (!vis_dev)
  6577. return;
  6578. #ifdef _PRINT_SUPPORT_
  6579. if (print_vd || print_preview_vd)
  6580. {
  6581. PrinterInfo* printer_info = GetWindow()->GetPrinterInfo(!print_vd);
  6582. if (printer_info)
  6583. {
  6584. scale = (scale * g_pcprint->GetIntegerPref(PrefsCollectionPrint::PrinterScale)) / 100;
  6585. print_preview_vd->SetScale(scale);
  6586. }
  6587. }
  6588. #endif // _PRINT_SUPPORT_
  6589. int old_scale = vis_dev->GetScale();
  6590. vis_dev->SetScale(scale);
  6591. #ifdef DOCHAND_HISTORY_SAVE_ZOOM_LEVEL
  6592. if (CurrentDocListElm())
  6593. CurrentDocListElm()->SetLastScale(scale);
  6594. #endif // DOCHAND_HISTORY_SAVE_ZOOM_LEVEL
  6595. if (FramesDocument* frames_doc = GetCurrentDoc())
  6596. {
  6597. // scale all frames and iframes
  6598. if (frames_doc->GetSubWinId() == -1)
  6599. {
  6600. DocumentTreeIterator it(this);
  6601. it.SetIncludeEmpty();
  6602. while (it.Next())
  6603. it.GetDocumentManager()->SetScale(scale);
  6604. }
  6605. if (scale != old_scale)
  6606. {
  6607. if (!GetWindow()->GetTrueZoom())
  6608. {
  6609. // Mark current selected element dirty
  6610. TextSelection* text_selection = frames_doc->GetTextSelection();
  6611. if (text_selection)
  6612. {
  6613. HTML_Element* element = text_selection->GetStartElement();
  6614. if (element)
  6615. {
  6616. element->MarkDirty(frames_doc);
  6617. text_selection->MarkDirty(element);
  6618. element = text_selection->GetEndElement();
  6619. if (element)
  6620. element->MarkDirty(frames_doc);
  6621. text_selection->MarkDirty(element);
  6622. }
  6623. }
  6624. if (HTML_Element* root = frames_doc->GetDocRoot())
  6625. root->RemoveCachedTextInfo(frames_doc);
  6626. }
  6627. if (frames_doc->GetSubWinId() == -1)
  6628. {
  6629. frames_doc->RecalculateLayoutViewSize(TRUE);
  6630. frames_doc->RecalculateScrollbars();
  6631. /* Update frames' geometry. Typically necessary for truezoom (and
  6632. in other cases), since that won't affect layout viewport size
  6633. (and thus there will be no reformatting) */
  6634. for (DocumentTreeIterator it(this); it.Next();)
  6635. if (FramesDocElm* fde = it.GetFramesDocElm())
  6636. fde->UpdateGeometry();
  6637. }
  6638. }
  6639. }
  6640. }
  6641. #if defined SAVE_DOCUMENT_AS_TEXT_SUPPORT
  6642. OP_STATUS DocumentManager::SaveCurrentDocAsText(UnicodeOutputStream* stream, const uni_char* fname, const char *force_encoding) // <##> can this return an error-code (or boolean) that the save was successful or not ? <JB>
  6643. {
  6644. # ifdef _PRINT_SUPPORT_
  6645. if (print_preview_vd)
  6646. return OpStatus::ERR;
  6647. # endif // _PRINT_SUPPORT_
  6648. if (FramesDocument* doc = GetCurrentDoc())
  6649. return doc->SaveCurrentDocAsText(stream, fname, force_encoding);
  6650. else
  6651. return OpStatus::ERR;
  6652. }
  6653. #endif // SAVE_DOCUMENT_AS_TEXT_SUPPORT
  6654. void DocumentManager::Clear()
  6655. {
  6656. is_clearing = TRUE;
  6657. #ifdef _PRINT_SUPPORT_
  6658. if (print_preview_doc)
  6659. OpStatus::Ignore(SetPrintMode(FALSE, NULL, TRUE));
  6660. if (print_doc)
  6661. OpStatus::Ignore(SetPrintMode(FALSE, NULL, FALSE));
  6662. #endif // _PRINT_SUPPORT_
  6663. StopLoading(FALSE, !GetFrame(), TRUE);
  6664. if (current_doc_elm && current_doc_elm->Doc())
  6665. {
  6666. OP_STATUS status = current_doc_elm->Doc()->Undisplay(TRUE);
  6667. if (OpStatus::IsMemoryError(status))
  6668. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  6669. }
  6670. current_doc_elm = NULL; // Important: GetCurrentDoc() may be called from Document destructor !!!
  6671. for (DocListElm* delm = LastDocListElm(); delm; delm = LastDocListElm())
  6672. {
  6673. if (delm->Number() >= GetWindow()->GetHistoryMax() || delm->Number() <= GetWindow()->GetHistoryMin())
  6674. GetWindow()->SetCheckHistory(TRUE);
  6675. delm->Out();
  6676. OP_DELETE(delm);
  6677. }
  6678. OP_DELETEA(current_application);
  6679. current_application = NULL;
  6680. is_clearing = FALSE;
  6681. OP_DELETE(m_waiting_for_online_url);
  6682. m_waiting_for_online_url = NULL;
  6683. #ifdef DOM_LOAD_TV_APP
  6684. SetWhitelist(NULL);
  6685. #endif
  6686. }
  6687. void DocumentManager::ClearHistory()
  6688. {
  6689. Clear();
  6690. history_len = 0;
  6691. if (vis_dev)
  6692. {
  6693. vis_dev->SetBgColor(g_pcfontscolors->GetColor(OP_SYSTEM_COLOR_DOCUMENT_BACKGROUND));
  6694. vis_dev->UpdateAll();
  6695. }
  6696. }
  6697. #ifdef _PRINT_SUPPORT_
  6698. OP_DOC_STATUS DocumentManager::PrintPage(PrintDevice* pd, int page_num, BOOL print_selected_only, BOOL only_probe)
  6699. {
  6700. if (FramesDocument *prnt_doc = GetPrintDoc())
  6701. {
  6702. if (only_probe)
  6703. // Don't print anything - just check if it is really possible to print the specified page
  6704. return page_num <= prnt_doc->CountPages() ? (OP_DOC_STATUS) OpStatus::OK : DocStatus::DOC_PAGE_OUT_OF_RANGE;
  6705. else
  6706. return prnt_doc->PrintPage(pd, page_num, print_selected_only);
  6707. }
  6708. else
  6709. return DocStatus::DOC_CANNOT_PRINT;
  6710. }
  6711. #endif // _PRINT_SUPPORT_
  6712. void DocumentManager::RaiseCondition(OP_STATUS status)
  6713. {
  6714. if (OpStatus::IsMemoryError(status))
  6715. {
  6716. if (window)
  6717. window->RaiseCondition(status);
  6718. else
  6719. g_memory_manager->RaiseCondition(status);
  6720. }
  6721. }
  6722. #ifdef _WML_SUPPORT_
  6723. //
  6724. // must be called at least once before parsing any
  6725. // WML documents
  6726. //**********************************************************************
  6727. OP_STATUS DocumentManager::WMLInit()
  6728. {
  6729. if (!wml_context)
  6730. {
  6731. wml_context = OP_NEW(WML_Context, (this));
  6732. if (!wml_context)
  6733. return OpStatus::ERR_NO_MEMORY;
  6734. if (OpStatus::IsMemoryError(wml_context->Init())
  6735. || OpStatus::IsMemoryError(wml_context->PreParse()))
  6736. {
  6737. OP_DELETE(wml_context);
  6738. wml_context = NULL;
  6739. return OpStatus::ERR_NO_MEMORY;
  6740. }
  6741. wml_context->IncRef();
  6742. current_doc_elm->SetWmlContext(wml_context); // store it in the document history
  6743. }
  6744. return OpStatus::OK;
  6745. }
  6746. // Sets a new context deleteing the old one.
  6747. OP_STATUS DocumentManager::WMLSetContext(WML_Context *new_context)
  6748. {
  6749. if (wml_context)
  6750. wml_context->DecRef();
  6751. wml_context = OP_NEW(WML_Context, (this));
  6752. if (!wml_context
  6753. || OpStatus::IsMemoryError(wml_context->Init())
  6754. || OpStatus::IsMemoryError(wml_context->Copy(new_context, this)))
  6755. {
  6756. OP_DELETE(wml_context);
  6757. wml_context = NULL;
  6758. return OpStatus::ERR_NO_MEMORY;
  6759. }
  6760. wml_context->IncRef();
  6761. if (current_doc_elm)
  6762. current_doc_elm->SetWmlContext(wml_context);
  6763. return OpStatus::OK;
  6764. }
  6765. // Delete the WML context
  6766. void DocumentManager::WMLDeleteContext()
  6767. {
  6768. if (wml_context)
  6769. wml_context->DecRef();
  6770. wml_context = NULL;
  6771. }
  6772. // Clean up the document history. Removes all cards beyond the first in the
  6773. // last WML session.
  6774. void DocumentManager::WMLDeWmlifyHistory(BOOL delete_all/*=FALSE*/)
  6775. {
  6776. int first = delete_all ? -2 : wml_context->GetFirstInSession();
  6777. // -1 indicates not set, -2 indicates delete all
  6778. if (first == -1)
  6779. return;
  6780. DocListElm* tmp_elm = (DocListElm *) doc_list.Last();
  6781. while (tmp_elm && tmp_elm->GetWmlContext() && tmp_elm->Number() > first)
  6782. {
  6783. DocListElm* pred_tmp_elm = tmp_elm->Pred();
  6784. if (tmp_elm != current_doc_elm)
  6785. RemoveElementFromHistory(tmp_elm, FALSE);
  6786. tmp_elm = pred_tmp_elm;
  6787. }
  6788. }
  6789. #endif // _WML_SUPPORT_
  6790. void DocumentManager::SetWaitingForOnlineUrl(URL &url)
  6791. {
  6792. OP_DELETE(m_waiting_for_online_url);
  6793. m_waiting_for_online_url = OP_NEW(URL, (url));
  6794. }
  6795. OP_STATUS DocumentManager::OnlineModeChanged()
  6796. {
  6797. if (m_waiting_for_online_url)
  6798. {
  6799. OpenURL(*m_waiting_for_online_url, referrer_url, TRUE/*check_if_expired*/, FALSE /*reload*/);
  6800. OP_DELETE(m_waiting_for_online_url);
  6801. m_waiting_for_online_url = NULL;
  6802. }
  6803. if (FramesDocument *frm_doc = GetCurrentDoc())
  6804. return frm_doc->OnlineModeChanged();
  6805. else
  6806. return OpStatus::OK;
  6807. }
  6808. BOOL DocumentManager::IsTrustedExternalURLProtocol(const OpStringC &URLName)
  6809. {
  6810. BOOL isTrusted = FALSE;
  6811. if (URLName.IsEmpty())
  6812. return isTrusted;
  6813. int colonindex = URLName.FindFirstOf(':');
  6814. if (colonindex != KNotFound)
  6815. {
  6816. int number_trusted_protocols = g_pcdoc->GetNumberOfTrustedProtocols();
  6817. if (number_trusted_protocols)
  6818. {
  6819. OpString protocol;
  6820. if (OpStatus::IsError(protocol.Set(URLName.CStr(), colonindex)))
  6821. return FALSE;
  6822. TrustedProtocolData data;
  6823. int index = g_pcdoc->GetTrustedProtocolInfo(protocol, data);
  6824. if (index != -1)
  6825. // Do not treat UseInternalApplication and UseWebService viewer modes as external. Check if the application's name is not empty too.
  6826. isTrusted = (data.viewer_mode == UseCustomApplication || data.viewer_mode == UseDefaultApplication) && !data.filename.IsEmpty();
  6827. }
  6828. }
  6829. // Done
  6830. return isTrusted;
  6831. }
  6832. #if defined WEB_HANDLERS_SUPPORT || defined QUICK
  6833. OP_BOOLEAN DocumentManager::AttemptExecuteURLsRecognizedByOpera(URL& url, DocumentReferrer referrer, BOOL user_initiated, BOOL user_started)
  6834. {
  6835. enum ExecuteAction
  6836. {
  6837. DoNotExecute,
  6838. ExecuteInOpera,
  6839. ExecuteSystemOrExternalApp,
  6840. #ifdef WEB_HANDLERS_SUPPORT
  6841. LoadWebApp
  6842. #endif // WEB_HANDLERS_SUPPORT
  6843. } execute_action = DoNotExecute;
  6844. OpString external_application;
  6845. // Check the list of trusted protocols.
  6846. OpString protocol;
  6847. if (execute_action == DoNotExecute)
  6848. {
  6849. if (url.IsEmpty())
  6850. return OpBoolean::IS_FALSE;
  6851. RETURN_IF_MEMORY_ERROR(protocol.Set(url.GetAttribute(URL::KProtocolName)));
  6852. TrustedProtocolData td;
  6853. OP_MEMORY_VAR int index = g_pcdoc->GetTrustedProtocolInfo(protocol, td);
  6854. if (index >= 0)
  6855. {
  6856. URLType url_type = url.Type();
  6857. switch (td.viewer_mode)
  6858. {
  6859. case UseCustomApplication:
  6860. {
  6861. if (url_type == URL_MAILTO)
  6862. {
  6863. execute_action = DoNotExecute;
  6864. }
  6865. else
  6866. {
  6867. execute_action = ExecuteSystemOrExternalApp;
  6868. }
  6869. RETURN_IF_MEMORY_ERROR(external_application.Set(td.filename));
  6870. break;
  6871. }
  6872. case UseInternalApplication:
  6873. {
  6874. execute_action = DoNotExecute;
  6875. break;
  6876. }
  6877. case UseDefaultApplication:
  6878. {
  6879. if (url_type == URL_MAILTO)
  6880. {
  6881. execute_action = DoNotExecute;
  6882. }
  6883. else
  6884. {
  6885. execute_action = ExecuteSystemOrExternalApp;
  6886. }
  6887. #ifdef OPSYSTEMINFO_GETPROTHANDLER
  6888. OpString uri_string;
  6889. RETURN_IF_MEMORY_ERROR(g_op_system_info->GetProtocolHandler(uri_string, protocol, external_application));
  6890. #endif // OPSYSTEMINFO_GETPROTHANDLER
  6891. break;
  6892. }
  6893. #ifdef WEB_HANDLERS_SUPPORT
  6894. case UseWebService:
  6895. {
  6896. if (td.web_handler.HasContent() && url.GetAttribute(URL::KHTTP_Method) == HTTP_METHOD_GET)
  6897. {
  6898. TempBuffer8 parameter_url8;
  6899. RETURN_IF_ERROR(parameter_url8.AppendURLEncoded(url.GetAttribute(URL::KName_With_Fragment_Escaped)));
  6900. OpString parameter_url16;
  6901. RETURN_IF_ERROR(parameter_url16.SetFromUTF8(parameter_url8.GetStorage()));
  6902. OpString target_url_str;
  6903. RETURN_IF_ERROR(target_url_str.Set(td.web_handler.CStr()));
  6904. RETURN_IF_ERROR(target_url_str.ReplaceAll(UNI_L("%s"), parameter_url16.CStr(), 1));
  6905. URL target_url = g_url_api->GetURL(url, target_url_str.CStr());
  6906. BOOL allowed;
  6907. OpSecurityContext source(url);
  6908. OpSecurityContext target(target_url);
  6909. target.AddText(protocol.CStr());
  6910. OP_STATUS rc = g_secman_instance->CheckSecurity(OpSecurityManager::WEB_HANDLER_REGISTRATION, source, target, allowed);
  6911. if (OpStatus::IsError(rc) || !allowed)
  6912. {
  6913. execute_action = DoNotExecute;
  6914. break;
  6915. }
  6916. OpString protocol2;
  6917. RETURN_IF_ERROR(protocol2.Set(target_url.GetAttribute(URL::KProtocolName, TRUE)));
  6918. TrustedProtocolData data2;
  6919. int index = g_pcdoc->GetTrustedProtocolInfo(protocol2, data2);
  6920. // Do not allow to use a handler for protocol the handler itself or any other handler uses.
  6921. if (protocol2.CompareI(url.GetAttribute(URL::KProtocolName, TRUE)) == 0)
  6922. {
  6923. execute_action = DoNotExecute;
  6924. break;
  6925. }
  6926. else if (index >= 0) // We have a handler for protocol this handler would like to use -> possible loop.
  6927. {
  6928. if (data2.viewer_mode == UseWebService)
  6929. {
  6930. execute_action = DoNotExecute;
  6931. break;
  6932. }
  6933. }
  6934. if (!td.user_defined)
  6935. {
  6936. OpString8 protocol8;
  6937. RETURN_IF_ERROR(protocol8.SetUTF8FromUTF16(td.protocol.CStr()));
  6938. WebHandlerCallback* cb = OP_NEW(WebHandlerCallback, (this, url, referrer, target_url, user_initiated, user_started, td.description.CStr(), TRUE, FALSE));
  6939. RETURN_OOM_IF_NULL(cb);
  6940. RETURN_IF_ERROR(cb->Construct(protocol8));
  6941. GetWindow()->GetWindowCommander()->GetDocumentListener()->OnWebHandler(GetWindow()->GetWindowCommander(), cb);
  6942. }
  6943. else // Open without asking
  6944. {
  6945. SetUrlLoadOnCommand(target_url, DocumentReferrer(current_url), TRUE, user_initiated);
  6946. GetMessageHandler()->PostMessage(MSG_URL_LOAD_NOW, target_url.Id(), user_initiated);
  6947. }
  6948. execute_action = LoadWebApp;
  6949. }
  6950. else
  6951. {
  6952. execute_action = DoNotExecute;
  6953. }
  6954. }
  6955. #endif // WEB_HANDLERS_SUPPORT
  6956. }
  6957. }
  6958. }
  6959. #ifdef M2_SUPPORT
  6960. // Check if we should execute this in M2.
  6961. if (execute_action == DoNotExecute)
  6962. {
  6963. switch (url.Type())
  6964. {
  6965. case URL_NEWS :
  6966. case URL_SNEWS :
  6967. #ifdef IRC_SUPPORT
  6968. case URL_IRC :
  6969. #endif
  6970. {
  6971. if( g_m2_engine )
  6972. {
  6973. execute_action = ExecuteInOpera;
  6974. }
  6975. break;
  6976. }
  6977. }
  6978. }
  6979. #endif
  6980. if (execute_action == ExecuteSystemOrExternalApp)
  6981. {
  6982. if (external_application.HasContent())
  6983. {
  6984. #ifdef QUICK
  6985. if (g_application)
  6986. g_application->ExecuteProgram(external_application.CStr(), url.UniName(PASSWORD_NOTHING), FALSE, protocol.CStr());
  6987. #else // QUICK
  6988. #ifdef EXTERNAL_APPLICATIONS_SUPPORT
  6989. g_op_system_info->ExecuteApplication(external_application,
  6990. url.GetAttribute(URL::KUniName_Username_Password_Escaped_NOT_FOR_UI).CStr());
  6991. #endif // EXTERNAL_APPLICATIONS_SUPPORT
  6992. #endif // QUICK
  6993. return OpBoolean::IS_TRUE;
  6994. }
  6995. #ifdef QUICK
  6996. else if (g_application)
  6997. {
  6998. g_application->ExecuteProgram(url.UniName(PASSWORD_NOTHING), 0);
  6999. return OpBoolean::IS_TRUE;
  7000. }
  7001. #endif // QUICK
  7002. }
  7003. #ifdef M2_SUPPORT
  7004. else if (execute_action == ExecuteInOpera)
  7005. {
  7006. // g_mailer_glue will be 0 if Opera runs with M2 disabled.
  7007. if( g_m2_engine )
  7008. {
  7009. RETURN_IF_MEMORY_ERROR(g_m2_engine->MailCommand(url));
  7010. return OpBoolean::IS_TRUE;
  7011. }
  7012. }
  7013. #endif // M2_SUPPORT
  7014. #ifdef WEB_HANDLERS_SUPPORT
  7015. else if (execute_action == LoadWebApp)
  7016. return OpBoolean::IS_TRUE;
  7017. #endif // WEB_HANDLERS_SUPPORT
  7018. return OpBoolean::IS_FALSE;
  7019. }
  7020. #endif // QUICK
  7021. OP_BOOLEAN
  7022. DocumentManager::JumpToRelativePosition(const URL &url, BOOL reuse_history_entry)
  7023. {
  7024. FramesDocument *doc = GetCurrentDoc();
  7025. OpString new_decoded_fragment;
  7026. OpString new_original_fragment;
  7027. RETURN_IF_ERROR(GetURLFragment(url, new_decoded_fragment, new_original_fragment));
  7028. uni_char* new_fragment_id = new_decoded_fragment.CStr();
  7029. // a relative anchor with just # should never reload page
  7030. if ((!new_fragment_id || *new_fragment_id)
  7031. && (load_stat != NOT_LOADING
  7032. && (load_stat != DOC_CREATED || doc->IsLoaded())
  7033. || !url_load_on_command.IsEmpty() || !doc
  7034. || !IsRelativeJump(url)))
  7035. // Not possible, need to load the new URL the normal way.
  7036. return OpBoolean::IS_FALSE;
  7037. OpString currently_loading_fragment;
  7038. RETURN_IF_ERROR(currently_loading_fragment.Set(current_doc_elm->GetUrl().UniRelName()));
  7039. if (!currently_loading_fragment.CStr() || !new_original_fragment.CStr() || currently_loading_fragment != new_original_fragment)
  7040. {
  7041. if (load_stat == NOT_LOADING && !reuse_history_entry)
  7042. {
  7043. StoreViewport(current_doc_elm);
  7044. DocListElm *dle = OP_NEW(DocListElm, (url, doc, FALSE, window->SetNewHistoryNumber(), GetNextDocListElmId()));
  7045. if (!dle)
  7046. return OpStatus::ERR_NO_MEMORY;
  7047. #ifdef _WML_SUPPORT_
  7048. // relative jumps is inside a deck and should use the same WML_Context
  7049. if (current_doc_elm->GetWmlContext())
  7050. dle->SetWmlContext(current_doc_elm->GetWmlContext());
  7051. #endif // _WML_SUPPORT_
  7052. InsertHistoryElement(dle);
  7053. dle->SetReferrerUrl(current_doc_elm->GetReferrerUrl(), ShouldSendReferrer());
  7054. current_doc_elm = dle;
  7055. }
  7056. else
  7057. current_doc_elm->SetUrl(url);
  7058. if (!window->IsLoading())
  7059. {
  7060. if (SignalOnNewPage(VIEWPORT_CHANGE_REASON_JUMP_TO_RELATIVE_POS))
  7061. waiting_for_document_ready = TRUE;
  7062. }
  7063. current_url = url;
  7064. doc->SetUrl(url);
  7065. WindowCommander *wc = GetWindow()->GetWindowCommander();
  7066. if (!GetParentDoc())
  7067. {
  7068. uni_char *tempname = Window::ComposeLinkInformation(url.GetAttribute(URL::KUniName_Username_Password_Hidden).CStr(), url.GetAttribute(URL::KUniFragment_Name).CStr());
  7069. if (tempname)
  7070. {
  7071. wc->GetLoadingListener()->OnUrlChanged(wc, tempname);
  7072. OP_DELETEA(tempname);
  7073. }
  7074. }
  7075. if (!window->IsLoading())
  7076. {
  7077. // These calls are only here to trick the (quick) UI to update the
  7078. // state of the back and forward buttons. If you know a better way
  7079. // to do that, please change this code.
  7080. wc->GetLoadingListener()->OnStartLoading(wc);
  7081. wc->GetLoadingListener()->OnLoadingFinished(wc, OpLoadingListener::LOADING_SUCCESS);
  7082. if (!window->GetPrivacyMode())
  7083. current_url.Access(TRUE);
  7084. }
  7085. }
  7086. if (new_fragment_id)
  7087. // new_fragment_id can be NULL if the URL code got an oom.
  7088. // SetRelativePos can return ERR if FramesDocument::doc is not set
  7089. // and that would abort this function. Just ignore that.
  7090. RETURN_IF_MEMORY_ERROR(doc->SetRelativePos(new_fragment_id, new_original_fragment.CStr()));
  7091. // must be done after SetRelativePos() because of WML stuff
  7092. if (!window->IsLoading())
  7093. g_windowManager->UpdateVisitedLinks(current_url, NULL);
  7094. CheckOnNewPageReady();
  7095. // Will do nothing if hashes are the same.
  7096. RETURN_IF_ERROR(doc->HandleHashChangeEvent(currently_loading_fragment.CStr(), new_original_fragment.CStr()));
  7097. return OpBoolean::IS_TRUE;
  7098. }
  7099. BOOL DocumentManager::IsRecursiveDocumentOpening(const URL& url, BOOL from_html_attribute)
  7100. {
  7101. // check if furl equals to any ancestor of this frame
  7102. FramesDocument* ancestor_doc = parent_doc;
  7103. // We don't allow deeper nesting than 20 frames. Anything that big is probably a DoS attack
  7104. // We also do not allow this url to appear more than twice as parent. We need to
  7105. // allow one level because pages sometimes behave differently depending on
  7106. // referer and then we allow one loop extra to be sure not to block any real sites.
  7107. int level_count = 0;
  7108. int loop_count = 0;
  7109. while (ancestor_doc)
  7110. {
  7111. level_count++;
  7112. if (ancestor_doc->GetURL() == url)
  7113. // If the url was set from an html attribute do not allow
  7114. // recursion.
  7115. if (from_html_attribute)
  7116. return TRUE;
  7117. else
  7118. loop_count++;
  7119. ancestor_doc = ancestor_doc->GetParentDoc();
  7120. }
  7121. return loop_count > 2 || level_count > 20;
  7122. }
  7123. void
  7124. DocumentManager::StoreRequestThreadInfo(ES_Thread *thread)
  7125. {
  7126. if (thread)
  7127. request_thread_info = thread->GetOriginInfo();
  7128. else
  7129. ResetRequestThreadInfo();
  7130. }
  7131. void
  7132. DocumentManager::ResetRequestThreadInfo()
  7133. {
  7134. request_thread_info.type = ES_THREAD_EMPTY;
  7135. }
  7136. BOOL
  7137. DocumentManager::IgnoreURLRequest(URL url, ES_Thread *thread)
  7138. {
  7139. if (DOM_Environment::IsCalledFromUnrequestedScript(thread))
  7140. return IsSpecialURL(url);
  7141. else
  7142. return FALSE;
  7143. }
  7144. DocumentManager::SecCheckRes DocumentManager::InitiateSecurityCheck(URL url, const DocumentReferrer& source)
  7145. {
  7146. SecCheckRes res = SEC_CHECK_DENIED;
  7147. security_check_callback->Reset();
  7148. security_check_callback->SetURLs(url, source);
  7149. URL source_url = source.url;
  7150. OP_STATUS status = g_secman_instance->CheckSecurity(OpSecurityManager::DOCMAN_URL_LOAD, OpSecurityContext(source_url, this), OpSecurityContext(url), security_check_callback);
  7151. if (OpStatus::IsError(status))
  7152. res = SEC_CHECK_DENIED;
  7153. else if (!security_check_callback->m_done)
  7154. return SEC_CHECK_STARTED;
  7155. else if (security_check_callback->m_allowed)
  7156. res = SEC_CHECK_ALLOWED;
  7157. if (res == SEC_CHECK_DENIED)
  7158. HandleURLAccessDenied(url, source.url);
  7159. else
  7160. security_check_callback->Reset();
  7161. return res;
  7162. }
  7163. void DocumentManager::HandleURLAccessDenied(URL url, URL source)
  7164. {
  7165. StopLoading(FALSE, TRUE, FALSE);
  7166. queue_messages = FALSE;
  7167. queued_messages.Clear();
  7168. security_check_callback->Reset();
  7169. #ifdef WEBSERVER_SUPPORT
  7170. if (url.GetAttribute(URL::KIsUniteServiceAdminURL))
  7171. RAISE_IF_MEMORY_ERROR(GenerateAndShowUniteWarning(url, source));
  7172. #endif // WEBSERVER_SUPPORT
  7173. #ifdef OPERA_CONSOLE
  7174. if (g_console->IsLogging())
  7175. {
  7176. OpConsoleEngine::Message msg(OpConsoleEngine::Network, OpConsoleEngine::Information);
  7177. msg.window = GetWindow()->Id();
  7178. // Eventually it would be nice to unescape the url to make it more readable, but then we need to
  7179. // get the decoding to do it correctly with respect to charset encodings. See bug 250545
  7180. OP_STATUS check = url.GetAttribute(URL::KUniName_With_Fragment_Escaped, msg.url);
  7181. if (OpStatus::IsSuccess(check))
  7182. {
  7183. check = g_languageManager->GetString(Str::S_SECURITY_LOADING_BLOCKED, msg.message);
  7184. if (OpStatus::IsSuccess(check))
  7185. TRAP(check, g_console->PostMessageL(&msg));
  7186. }
  7187. if (OpStatus::IsMemoryError(check))
  7188. RaiseCondition(OpStatus::ERR_NO_MEMORY);
  7189. }
  7190. #endif // OPERA_CONSOLE
  7191. if (!current_doc_elm && frame)
  7192. FramesDocument::CheckOnLoad(NULL, frame);
  7193. }
  7194. /* static */ BOOL
  7195. DocumentManager::IsSpecialURL(URL target)
  7196. {
  7197. switch (target.Type())
  7198. {
  7199. case URL_MAILTO:
  7200. #ifdef IRC_SUPPORT
  7201. case URL_IRC:
  7202. #endif
  7203. return TRUE;
  7204. case URL_JAVASCRIPT:
  7205. return FALSE;
  7206. default:
  7207. return !g_url_api->LoadAndDisplayPermitted(target);
  7208. }
  7209. }
  7210. #ifdef SCOPE_PROFILER
  7211. OP_STATUS
  7212. DocumentManager::StartProfiling(OpProfilingSession *session)
  7213. {
  7214. if (IsProfiling() || !session)
  7215. return OpStatus::ERR;
  7216. m_timeline = session->AddTimeline(this);
  7217. return m_timeline ? OpStatus::OK : OpStatus::ERR_NO_MEMORY;
  7218. }
  7219. void
  7220. DocumentManager::StopProfiling()
  7221. {
  7222. m_timeline = NULL;
  7223. }
  7224. void
  7225. DocumentManager::OnAddChild(DocumentManager *child)
  7226. {
  7227. OpProfilingSession *session = window->GetProfilingSession();
  7228. // If this Window is currently profiling, also start profiling on the
  7229. // DocumentManager that was just added to the tree.
  7230. if (session)
  7231. RAISE_IF_MEMORY_ERROR(child->StartProfiling(session));
  7232. }
  7233. void
  7234. DocumentManager::OnRemoveChild(DocumentManager *child)
  7235. {
  7236. child->StopProfiling();
  7237. }
  7238. #endif // SCOPE_PROFILER
  7239. DocumentTreeIterator::DocumentTreeIterator()
  7240. : start(NULL),
  7241. current(NULL),
  7242. include_this(FALSE),
  7243. include_iframes(TRUE),
  7244. include_empty(FALSE)
  7245. {
  7246. }
  7247. DocumentTreeIterator::DocumentTreeIterator(Window *window)
  7248. : start(window->DocManager()),
  7249. current(window->DocManager()),
  7250. include_this(FALSE),
  7251. include_iframes(TRUE),
  7252. include_empty(FALSE)
  7253. {
  7254. }
  7255. DocumentTreeIterator::DocumentTreeIterator(DocumentManager *docman)
  7256. : start(docman),
  7257. current(docman),
  7258. include_this(FALSE),
  7259. include_iframes(TRUE),
  7260. include_empty(FALSE)
  7261. {
  7262. }
  7263. DocumentTreeIterator::DocumentTreeIterator(FramesDocElm *frame)
  7264. : start(frame->GetDocManager()),
  7265. current(frame->GetDocManager()),
  7266. include_this(FALSE),
  7267. include_iframes(TRUE),
  7268. include_empty(FALSE)
  7269. {
  7270. }
  7271. DocumentTreeIterator::DocumentTreeIterator(FramesDocument *document)
  7272. : start(document->GetDocManager()),
  7273. current(document->GetDocManager()),
  7274. include_this(FALSE),
  7275. include_iframes(TRUE),
  7276. include_empty(FALSE)
  7277. {
  7278. }
  7279. void DocumentTreeIterator::SetIncludeThis()
  7280. {
  7281. include_this = TRUE;
  7282. }
  7283. void DocumentTreeIterator::SetExcludeIFrames()
  7284. {
  7285. include_iframes = FALSE;
  7286. }
  7287. void DocumentTreeIterator::SetIncludeEmpty()
  7288. {
  7289. include_empty = TRUE;
  7290. }
  7291. BOOL DocumentTreeIterator::Next(BOOL skip_children)
  7292. {
  7293. if (include_this)
  7294. {
  7295. include_this = FALSE;
  7296. if (include_empty || current->GetCurrentDoc())
  7297. return TRUE;
  7298. }
  7299. FramesDocument *document = current->GetCurrentDoc();
  7300. FramesDocElm *frame = current->GetFrame();
  7301. if (document && !skip_children)
  7302. if (FramesDocElm *frm_root = document->GetFrmDocRoot())
  7303. frame = frm_root;
  7304. else if (include_iframes)
  7305. {
  7306. if (FramesDocElm *ifrm_root = document->GetIFrmRoot())
  7307. if (!ifrm_root->Empty())
  7308. frame = ifrm_root;
  7309. }
  7310. BOOL was_frame_root = TRUE;
  7311. while (frame)
  7312. {
  7313. FramesDocElm *leaf = (FramesDocElm *) frame->FirstLeaf();
  7314. if (leaf == frame)
  7315. leaf = NextLeaf(frame);
  7316. frame = leaf;
  7317. if (frame)
  7318. do
  7319. if (include_empty || frame->GetCurrentDoc())
  7320. {
  7321. current = frame->GetDocManager();
  7322. return TRUE;
  7323. }
  7324. while ((frame = NextLeaf(frame)) != 0);
  7325. if (current == start)
  7326. return FALSE;
  7327. if (was_frame_root)
  7328. {
  7329. frame = current->GetFrame();
  7330. was_frame_root = FALSE;
  7331. }
  7332. else if (FramesDocument *parent_document = current->GetParentDoc())
  7333. {
  7334. current = parent_document->GetDocManager();
  7335. frame = current->GetFrame();
  7336. }
  7337. else
  7338. return FALSE;
  7339. }
  7340. return FALSE;
  7341. }
  7342. void DocumentTreeIterator::SkipTo(DocumentManager* doc_man)
  7343. {
  7344. current = doc_man;
  7345. }
  7346. DocumentManager *DocumentTreeIterator::GetDocumentManager()
  7347. {
  7348. return current;
  7349. }
  7350. FramesDocElm *DocumentTreeIterator::GetFramesDocElm()
  7351. {
  7352. return current->GetFrame();
  7353. }
  7354. FramesDocument *DocumentTreeIterator::GetFramesDocument()
  7355. {
  7356. return current->GetCurrentDoc();
  7357. }
  7358. FramesDocElm* DocumentTreeIterator::NextLeaf(FramesDocElm* frame) const
  7359. {
  7360. FramesDocElm* leaf = frame;
  7361. FramesDocElm* subtree_root = start->GetFrame();
  7362. if (leaf == subtree_root)
  7363. // No more leaf nodes in this subtree.
  7364. return NULL;
  7365. while (!leaf->Suc())
  7366. {
  7367. // If leaf doesn't have a successor, go looking in parent
  7368. if (leaf == subtree_root)
  7369. // No more leaf nodes in this subtree.
  7370. return NULL;
  7371. leaf = leaf->Parent();
  7372. if (!leaf)
  7373. return NULL;
  7374. }
  7375. leaf = leaf->Suc();
  7376. // Then, traverse down leaf to find first child, if it has any
  7377. while (leaf->FirstChild())
  7378. leaf = leaf->FirstChild();
  7379. return leaf;
  7380. }
  7381. void
  7382. DocumentManager::PostDelayedActionMessage(int delay_ms)
  7383. {
  7384. double new_target_time = g_op_time_info->GetRuntimeMS() + delay_ms;
  7385. if (is_delayed_action_msg_posted && target_time_for_delayed_action_msg > new_target_time)
  7386. {
  7387. // Someone wants something to happen more urgently so delete the slow message.
  7388. mh->RemoveDelayedMessage(MSG_DOC_DELAYED_ACTION, 0, 0);
  7389. is_delayed_action_msg_posted = FALSE;
  7390. }
  7391. if (!is_delayed_action_msg_posted)
  7392. {
  7393. mh->PostMessage(MSG_DOC_DELAYED_ACTION, 0, 0, delay_ms);
  7394. is_delayed_action_msg_posted = TRUE;
  7395. target_time_for_delayed_action_msg = new_target_time;
  7396. }
  7397. }
  7398. #ifdef TRUST_RATING
  7399. OP_STATUS
  7400. DocumentManager::CheckTrustRating(URL url, BOOL offline_check_only, BOOL force_check)
  7401. {
  7402. TrustRating rating = Not_Set;
  7403. OP_STATUS status = OpStatus::OK;
  7404. BOOL check_done = TRUE;
  7405. OP_ASSERT(!url.IsEmpty());
  7406. if (!parent_doc)
  7407. GetWindow()->SetTrustRating(Not_Set, TRUE);
  7408. BOOL online_check_allowed = !offline_check_only && (force_check || g_pcnet->GetIntegerPref(PrefsCollectionNetwork::EnableTrustRating));
  7409. if (url.Type() != URL_JAVASCRIPT
  7410. #ifdef SELFTEST
  7411. && !url.GetAttribute(URL::KIsGeneratedBySelfTests)
  7412. #endif // SELFTEST
  7413. )
  7414. {
  7415. BOOL need_online;
  7416. RETURN_IF_ERROR(ServerTrustChecker::GetTrustRating(url, rating, need_online));
  7417. if (need_online && online_check_allowed)
  7418. {
  7419. BOOL is_local, need_resolve;
  7420. RETURN_IF_ERROR(ServerTrustChecker::IsLocalURL(url, is_local, need_resolve));
  7421. if (is_local)
  7422. rating = Unknown_Trust;
  7423. else
  7424. {
  7425. RETURN_IF_ERROR(AddTrustCheck(url, need_resolve));
  7426. check_done = FALSE;
  7427. }
  7428. }
  7429. else
  7430. {
  7431. ServerName *server_name = url.GetServerName();
  7432. if (server_name && rating == Untrusted_Ask_Advisory /* site is untrusted but advisory must be asked to get known real trusting rate */)
  7433. {
  7434. Advisory *sn_advisory = server_name->GetAdvisory(url.GetAttribute(URL::KUniName));
  7435. TrustInfoParser::Advisory advisory;
  7436. if (sn_advisory)
  7437. {
  7438. advisory.homepage_url = sn_advisory->homepage.CStr();
  7439. advisory.advisory_url = sn_advisory->advisory.CStr();
  7440. advisory.text = sn_advisory->text.CStr();
  7441. advisory.type = sn_advisory->type;
  7442. advisory.id = sn_advisory->src;
  7443. if (sn_advisory->type == SERVER_SIDE_FRAUD_MALWARE)
  7444. {
  7445. rating = Malware;
  7446. }
  7447. else if (sn_advisory->type == SERVER_SIDE_FRAUD_PHISHING)
  7448. {
  7449. rating = Phishing;
  7450. }
  7451. else
  7452. {
  7453. rating = Unknown_Trust;
  7454. }
  7455. }
  7456. else // rating is Ask_Avisory but advisory is not going to tell anything so set phishing
  7457. rating = Phishing;
  7458. // if site is phishing or offers malware generate warning page if not already bypassed
  7459. if ((rating == Phishing || rating == Malware) && !server_name->GetTrustRatingBypassed())
  7460. {
  7461. if (OpStatus::IsSuccess(status = GenerateAndShowFraudWarningPage(url, &advisory)))
  7462. status = OpStatus::ERR_NO_ACCESS;
  7463. }
  7464. // Prevent the destructor from deallocating these strings.
  7465. advisory.homepage_url = NULL;
  7466. advisory.advisory_url = NULL;
  7467. advisory.text = NULL;
  7468. }
  7469. }
  7470. }
  7471. if (check_done) // Notify the final rating if the check is done.
  7472. {
  7473. /** Don't leave the rating as Not_Set unless it couldn't be checked for real
  7474. * e.g. due to the fraud checking feature disabled. */
  7475. if (rating == Not_Set && online_check_allowed)
  7476. rating = Unknown_Trust;
  7477. GetWindow()->SetTrustRating(rating);
  7478. }
  7479. return status;
  7480. }
  7481. OP_STATUS DocumentManager::AddTrustCheck(URL url, BOOL need_ip_resolve)
  7482. {
  7483. OP_ASSERT(!url.IsEmpty());
  7484. // Check if we're already checking this server:
  7485. for (ServerTrustChecker* check = (ServerTrustChecker*)m_active_trust_checks.First();
  7486. check;
  7487. check = (ServerTrustChecker*)check->Suc())
  7488. {
  7489. if (check->URLBelongsToThisServer(url))
  7490. {
  7491. if (!check->IsCheckingURL(url))
  7492. RETURN_IF_ERROR(check->AddURL(url));
  7493. return OpStatus::OK;
  7494. }
  7495. }
  7496. // Need to start a new check
  7497. ServerTrustChecker* checker = OP_NEW(ServerTrustChecker, (m_next_checker_id++, this));
  7498. if (!checker)
  7499. return OpStatus::ERR_NO_MEMORY;
  7500. OP_STATUS status = checker->Init(url);
  7501. if (OpStatus::IsSuccess(status))
  7502. status = checker->StartCheck(need_ip_resolve);
  7503. if (OpStatus::IsSuccess(status))
  7504. checker->Into(&m_active_trust_checks);
  7505. else
  7506. OP_DELETE(checker);
  7507. return status;
  7508. }
  7509. OP_STATUS DocumentManager::GenerateAndShowFraudWarningPage(const URL& blocked_url, TrustInfoParser::Advisory *advisory)
  7510. {
  7511. OP_ASSERT(blocked_url.GetServerName() != NULL);
  7512. GetCurrentURL().StopLoading(GetMessageHandler());
  7513. URL fraud_warning_url = g_url_api->GetURL(PHISHING_WARNING_URL);
  7514. g_url_api->MakeUnique(fraud_warning_url);
  7515. fraud_warning_url.Unload();
  7516. OperaFraudWarning redirect_page(fraud_warning_url, blocked_url, advisory);
  7517. RETURN_IF_ERROR(redirect_page.GenerateData());
  7518. RETURN_IF_ERROR(fraud_warning_url.SetAttribute(URL::KIsClickThroughPage, TRUE));
  7519. RETURN_IF_ERROR(fraud_warning_url.SetAttribute(URL::KReferrerURL, blocked_url));
  7520. /*
  7521. The fraud checker blocked 'url'. However, because the fraud check is async, if it was slow,
  7522. 'url' could have been redirected one or more times and the document being rendered being a
  7523. bit ahead in the redirect chain.
  7524. Or the reverse might also happen. Fraud check was too quick and the document has not yet
  7525. received a single header.
  7526. So, check if the last url in both redirect chains are the same.
  7527. */
  7528. if (CurrentDocListElm() != NULL && blocked_url.Id(TRUE) == CurrentDocListElm()->GetUrl().Id(TRUE))
  7529. SetUseHistoryNumber(CurrentDocListElm()->Number());
  7530. URL empty_url;
  7531. OpenURL(fraud_warning_url, DocumentReferrer(empty_url), FALSE, FALSE);
  7532. return OpStatus::OK;
  7533. }
  7534. #endif // TRUST_RATING
  7535. #ifdef ERROR_PAGE_SUPPORT
  7536. OP_STATUS DocumentManager::GenerateAndShowCrossNetworkErrorPage(const URL& blocked_url, Str::LocaleString error)
  7537. {
  7538. OP_ASSERT(blocked_url.GetServerName() != NULL);
  7539. GetCurrentURL().StopLoading(GetMessageHandler());
  7540. URL crossnet_warning_url = g_url_api->GetURL(OPERA_CROSS_NETWORK_ERROR_URL);
  7541. g_url_api->MakeUnique(crossnet_warning_url);
  7542. crossnet_warning_url.Unload();
  7543. OpCrossNetworkError redirect_page(crossnet_warning_url, error, blocked_url);
  7544. RETURN_IF_ERROR(redirect_page.GenerateData());
  7545. RETURN_IF_ERROR(crossnet_warning_url.SetAttribute(URL::KIsClickThroughPage, TRUE));
  7546. RETURN_IF_ERROR(crossnet_warning_url.SetAttribute(URL::KReferrerURL, blocked_url));
  7547. URL empty_url;
  7548. OpenURL(crossnet_warning_url, DocumentReferrer(empty_url), FALSE, FALSE);
  7549. return OpStatus::OK;
  7550. }
  7551. OP_STATUS DocumentManager::GenerateAndShowClickJackingBlock(const URL& blocked_url)
  7552. {
  7553. OP_ASSERT(blocked_url.GetServerName() != NULL || blocked_url.Type() == URL_OPERA);
  7554. GetCurrentURL().StopLoading(GetMessageHandler());
  7555. URL clickjack_url = g_url_api->GetURL(OPERA_CLICKJACK_BLOCK_URL);
  7556. g_url_api->MakeUnique(clickjack_url);
  7557. clickjack_url.Unload();
  7558. OpClickJackingBlock error_page(clickjack_url, blocked_url);
  7559. RETURN_IF_ERROR(error_page.GenerateData());
  7560. RETURN_IF_ERROR(clickjack_url.SetAttribute(URL::KIsClickThroughPage, TRUE));
  7561. RETURN_IF_ERROR(clickjack_url.SetAttribute(URL::KReferrerURL, blocked_url));
  7562. if (CurrentDocListElm())
  7563. SetUseHistoryNumber(CurrentDocListElm()->Number());
  7564. else if (GetParentDoc() && GetParentDoc()-> GetDocManager()->CurrentDocListElm())
  7565. SetUseHistoryNumber(GetParentDoc()-> GetDocManager()->CurrentDocListElm()->Number());
  7566. URL empty_url;
  7567. OpenURL(clickjack_url, DocumentReferrer(empty_url), FALSE, FALSE);
  7568. return OpStatus::OK;
  7569. }
  7570. OP_STATUS
  7571. DocumentManager::HandleClickThroughUrl(URL& url, DocumentReferrer& ref_url)
  7572. {
  7573. if (url.Type() == URL_OPERA && ref_url.url.Type() == URL_OPERA &&
  7574. ref_url.url.GetAttribute(URL::KIsClickThroughPage))
  7575. {
  7576. // This if block detects when a opera: link is clicked inside another opera: page.
  7577. OP_ASSERT(ref_url.url.GetAttribute(URL::KIsGeneratedByOpera));
  7578. OpString8 referrer_str, url_str;
  7579. RETURN_IF_ERROR(ref_url.url.GetAttribute(URL::KName, referrer_str));
  7580. if (referrer_str.Compare(OPERA_CROSS_NETWORK_ERROR_URL) == 0)
  7581. {
  7582. // Our friendly cross-network error page !
  7583. RETURN_IF_ERROR(url.GetAttribute(URL::KName, url_str));
  7584. #if defined PREFS_WRITE && defined PREFS_HOSTOVERRIDE
  7585. if (url_str.Compare("opera:proceed/override") == 0)
  7586. {
  7587. url = ref_url.url.GetAttribute(URL::KReferrerURL);
  7588. ref_url = DocumentReferrer();
  7589. OP_ASSERT(url.GetServerName() != NULL);
  7590. TRAP_AND_RETURN(status, g_pcnet->OverridePrefL(url.GetServerName()->UniName(), PrefsCollectionNetwork::AllowCrossNetworkNavigation, 1, TRUE));
  7591. // Replace the current history position, so we don't
  7592. // get a history entry with the click-through page.
  7593. if (CurrentDocListElm())
  7594. SetUseHistoryNumber(CurrentDocListElm()->Number());
  7595. }
  7596. else
  7597. #endif //PREFS_HOSTOVERRIDE
  7598. if (url_str.Compare("opera:proceed") == 0)
  7599. {
  7600. url = ref_url.url.GetAttribute(URL::KReferrerURL);
  7601. ref_url = DocumentReferrer();
  7602. OP_ASSERT(url.GetServerName() != NULL);
  7603. // Let the host be resolved again.
  7604. url.GetServerName()->SetNetType(NETTYPE_UNDETERMINED);
  7605. // Replace the current history position, so we don't
  7606. // get a history entry with the click-through page.
  7607. if (CurrentDocListElm())
  7608. SetUseHistoryNumber(CurrentDocListElm()->Number());
  7609. }
  7610. else
  7611. {
  7612. // Perhaps harmess, but still we should make sure all opera:links are properly handled.
  7613. OP_ASSERT(!"What did you click ?");
  7614. }
  7615. return OpStatus::OK;
  7616. }
  7617. #ifdef TRUST_RATING
  7618. else if (referrer_str.Compare(PHISHING_WARNING_URL) == 0)
  7619. {
  7620. // Our friendly phishing protection page
  7621. RETURN_IF_ERROR(url.GetAttribute(URL::KName, url_str));
  7622. if (url_str.Compare("opera:proceed") == 0)
  7623. {
  7624. url = ref_url.url.GetAttribute(URL::KReferrerURL);
  7625. ref_url = DocumentReferrer();
  7626. OP_ASSERT(url.GetServerName() != NULL);
  7627. // If the refering URL is a opera:site-warning URL, then it's
  7628. // the 'I want to get scammed link' in a phishing site warning
  7629. // so allow user to access the site even if it's unsafe.
  7630. url.GetServerName()->SetTrustRatingBypassed(TRUE);
  7631. // Replace the current history position, so we don't
  7632. // get a history entry with the click-through page.
  7633. if (CurrentDocListElm())
  7634. SetUseHistoryNumber(CurrentDocListElm()->Number());
  7635. }
  7636. else if (url_str.Compare("opera:back") == 0)
  7637. {
  7638. GetWindow()->SetHistoryPrev();
  7639. return OpStatus::ERR; // Prevent continue loading the url, given that we just navigated backwards in history.
  7640. }
  7641. else
  7642. {
  7643. // Perhaps harmess, but still we should make sure all opera:links are properly handled.
  7644. OP_ASSERT(!"What did you click ?");
  7645. }
  7646. return OpStatus::OK;
  7647. }
  7648. #endif // TRUST_RATING
  7649. else if (referrer_str.Compare(OPERA_CLICKJACK_BLOCK_URL) == 0)
  7650. {
  7651. RETURN_IF_ERROR(url.GetAttribute(URL::KName, url_str));
  7652. if (url_str.Compare("opera:proceed") == 0)
  7653. {
  7654. URL blocked_url = ref_url.url.GetAttribute(URL::KReferrerURL);
  7655. OP_ASSERT(!blocked_url.IsEmpty());
  7656. DocumentReferrer ref;
  7657. if (GetParentDoc())
  7658. {
  7659. // Regular click in the frame.
  7660. GetWindow()->GetClickedURL(blocked_url, ref, -2, TRUE, FALSE);
  7661. return OpStatus::ERR; // Prevent continue loading the url, given that this just opened a new window.
  7662. }
  7663. else
  7664. {
  7665. // Middle click or ctrl+shift click: this call to
  7666. // DocMgr::OpenURL already happens under the new Window
  7667. // in the top level DocumentManager.
  7668. url = blocked_url;
  7669. ref_url = DocumentReferrer();
  7670. }
  7671. }
  7672. else
  7673. {
  7674. // Perhaps harmess, but still we should make sure all opera:links are properly handled.
  7675. OP_ASSERT(!"What did you click ?");
  7676. }
  7677. }
  7678. }
  7679. return OpStatus::OK;
  7680. }
  7681. #endif // ERROR_PAGE_SUPPORT
  7682. #ifdef WEBSERVER_SUPPORT
  7683. class UniteURL_Generator : public OperaURL_Generator
  7684. {
  7685. public:
  7686. virtual GeneratorMode GetMode() const { return KGenerateLoadHandler; }
  7687. };
  7688. OP_STATUS DocumentManager::GenerateAndShowUniteWarning(URL &url, URL& source)
  7689. {
  7690. if (!g_opera->dochand_module.unitewarningpage_generator)
  7691. {
  7692. UniteURL_Generator* unite_error_page_address = OP_NEW(UniteURL_Generator, ());
  7693. if (!unite_error_page_address)
  7694. return OpStatus::ERR_NO_MEMORY;
  7695. OP_STATUS status = unite_error_page_address->Construct(UNITE_WARNING_PAGE_URL, FALSE);
  7696. if (OpStatus::IsError(status))
  7697. {
  7698. OP_DELETE(unite_error_page_address);
  7699. return status;
  7700. }
  7701. g_opera->dochand_module.unitewarningpage_generator = unite_error_page_address;
  7702. g_url_api->RegisterOperaURL(unite_error_page_address);
  7703. }
  7704. URL warning_url = g_url_api->GetURL("opera:" UNITE_WARNING_PAGE_URL, source.GetContextId());
  7705. g_url_api->MakeUnique(warning_url);
  7706. BOOL block_access = GetParentDoc() != NULL; // block iframes/frames completely
  7707. OperaUniteAdminWarningURL warning_page(warning_url, url, block_access);
  7708. RETURN_IF_ERROR(warning_page.GenerateData());
  7709. OpenURL(warning_url, DocumentReferrer(source), FALSE, FALSE);
  7710. return OpStatus::OK;
  7711. }
  7712. #endif // WEBSERVER_SUPPORT
  7713. #ifdef WEB_TURBO_MODE
  7714. OP_STATUS DocumentManager::UpdateTurboMode()
  7715. {
  7716. DocumentTreeIterator iter(this);
  7717. iter.SetIncludeThis();
  7718. while (iter.Next(FALSE))
  7719. {
  7720. FramesDocument *doc = iter.GetFramesDocument();
  7721. if (doc && doc->GetLogicalDocument())
  7722. RETURN_IF_MEMORY_ERROR(doc->GetLogicalDocument()->UpdateTurboMode());
  7723. }
  7724. return OpStatus::OK;
  7725. }
  7726. #endif // WEB_TURBO_MODE
  7727. BOOL DocumentManager::DisplayContentIfAvailable(URL &url, URL_ID url_id, MH_PARAM_2 load_status)
  7728. {
  7729. BOOL network_error = load_status == ERR_NETWORK_PROBLEM || load_status == ERR_COMM_NETWORK_UNREACHABLE ||
  7730. load_status == ERR_COMM_CONNECT_FAILED || load_status == ERR_CONNECT_TIMED_OUT ||
  7731. load_status == ERR_COMM_PROXY_CONNECT_FAILED || load_status == ERR_COMM_PROXY_HOST_NOT_FOUND ||
  7732. load_status == ERR_COMM_PROXY_HOST_UNAVAILABLE || load_status == ERR_COMM_PROXY_CONNECTION_REFUSED;
  7733. if (!network_error && //network error implies that no new content is available
  7734. url.ContentLoaded() > 0 &&
  7735. !url.GetAttribute(URL::KIsGeneratedByOpera, TRUE))
  7736. {
  7737. if (load_stat == WAIT_FOR_HEADER || load_stat == WAIT_FOR_ACTION)
  7738. HandleHeaderLoaded(url_id, TRUE);
  7739. else
  7740. HandleDataLoaded(url_id);
  7741. return TRUE;
  7742. }
  7743. return FALSE;
  7744. }
  7745. /* virtual */
  7746. void
  7747. DocumentManager::SecurityCheckCallback::OnSecurityCheckSuccess(BOOL allowed, ChoicePersistenceType /*type*/)
  7748. {
  7749. SecurityCheckFinished();
  7750. m_allowed = allowed;
  7751. if (m_invalidated)
  7752. {
  7753. OP_DELETE(this);
  7754. return;
  7755. }
  7756. if (!m_suspended)
  7757. return;
  7758. if (allowed)
  7759. {
  7760. if (m_redirect)
  7761. {
  7762. if (!m_docman->queued_messages.Empty())
  7763. m_docman->mh->PostMessage(MSG_DOCHAND_PROCESS_QUEUED_MESSAGE, 0, 0);
  7764. else
  7765. m_docman->queue_messages = FALSE;
  7766. }
  7767. else
  7768. m_docman->OpenURL(m_url, m_referrer, m_check_if_expired, m_reload, m_options);
  7769. }
  7770. else
  7771. m_docman->HandleURLAccessDenied(m_url, m_referrer.url);
  7772. }
  7773. /* virtual */
  7774. void
  7775. DocumentManager::SecurityCheckCallback::OnSecurityCheckError(OP_STATUS error)
  7776. {
  7777. SecurityCheckFinished();
  7778. m_allowed = FALSE;
  7779. if (m_invalidated)
  7780. {
  7781. OP_DELETE(this);
  7782. return;
  7783. }
  7784. if (m_suspended)
  7785. m_docman->HandleURLAccessDenied(m_url, m_referrer.url);
  7786. }
  7787. void
  7788. DocumentManager::SecurityCheckCallback::SecurityCheckFinished()
  7789. {
  7790. m_done = TRUE;
  7791. Remove();
  7792. if (m_options.origin_thread)
  7793. m_options.origin_thread->Unblock();
  7794. }
  7795. void
  7796. DocumentManager::SecurityCheckCallback::SetURLs(URL& url, const DocumentReferrer& referrer)
  7797. {
  7798. m_url = url;
  7799. m_referrer = referrer;
  7800. }
  7801. void
  7802. DocumentManager::SecurityCheckCallback::PrepareForSuspending(BOOL check_if_expired, BOOL reload, const OpenURLOptions& options)
  7803. {
  7804. m_suspended = TRUE;
  7805. m_check_if_expired = check_if_expired;
  7806. m_reload = reload;
  7807. m_options = options;
  7808. if (options.origin_thread)
  7809. {
  7810. options.origin_thread->Block();
  7811. options.origin_thread->AddListener(this);
  7812. }
  7813. }
  7814. void
  7815. DocumentManager::SecurityCheckCallback::PrepareForSuspendingRedirect()
  7816. {
  7817. m_suspended = TRUE;
  7818. m_redirect = TRUE;
  7819. // Turn on message queuing to ensure that all redirects are
  7820. // security checked before MSG_URL_LOADED for the final redirect
  7821. // target is delivered.
  7822. m_docman->queue_messages = TRUE;
  7823. }
  7824. void
  7825. DocumentManager::SecurityCheckCallback::Reset()
  7826. {
  7827. m_done = FALSE;
  7828. m_suspended = FALSE;
  7829. m_redirect = FALSE;
  7830. m_allowed = FALSE;
  7831. m_invalidated = FALSE;
  7832. }
  7833. /* virtual */ OP_STATUS
  7834. DocumentManager::SecurityCheckCallback::Signal(ES_Thread *thread, ES_ThreadSignal signal)
  7835. {
  7836. OP_ASSERT(m_options.origin_thread == thread);
  7837. switch (signal)
  7838. {
  7839. case ES_SIGNAL_FAILED:
  7840. case ES_SIGNAL_FINISHED:
  7841. case ES_SIGNAL_CANCELLED:
  7842. m_options.origin_thread = NULL;
  7843. Remove();
  7844. break;
  7845. }
  7846. return OpStatus::OK;
  7847. }
  7848. void
  7849. DocumentManager::SetAction(ViewAction act)
  7850. {
  7851. #ifdef WEB_HANDLERS_SUPPORT
  7852. if (!action_locked)
  7853. #endif // WEB_HANDLERS_SUPPORT
  7854. current_action = act;
  7855. }