th @500!m Goals: "o !romote e#!$oration o% a ne& $ang'age ()a*ascri!t+ "o $earn abo't com!arators "o b'nd$e '! a so$'tion %or de!$oyment (ma,e a Chrome e#tension+ "o gain %ami$iarity &ith the -oc'ment Ob.ect /ode$ (-O/+ Prelude: Since yo'0$$ be 'sing Chrome e*ent'a$$y, 10d s'ggest starting it '! and going into the Conso$e %or the de*e$o!er too$s (yo' can get to it by c$ic,ing the b'tton beside the 0omnibo#0, c$ic,ing 0"oo$s0, and choosing 0)a*aScri!t Conso$e02 or yo' can .'st right3c$ic, on near$y any &eb!age, choose 01ns!ect 4$ement0, and then c$ic, on the 0Conso$e0 tab+5 6o' can 'se it to easi$y test sni!!ets o% code5 S're, there are too$s that gi*e yo' command3$ine )a*ascri!t, b't, $i,e 1 said, yo'0$$ need Chrome e*ent'a$$y anyhoo5 Post-Prelude: "he idea %or this assignment is that yo'0d be doing most o% the research yo'rse$%5 10$$ gi*e yo' a tas,, and yo' $earn ho& to so$*e it, &ith re$ati*e$y $itt$e hand3ho$ding5 Persona$$y, 10d s'ggest doing it that &ay5 7o&e*er, since not e*erybody is com%ortab$e &ith that a!!roach (%or some reason, some !eo!$e don0t $i,e %ee$ing $ost, con%'sed and %r'strated5 8o %ig're+, 10*e a$so inc$'ded a some&hat hand3ho$dy e#!$anation as &e$$5 1% that0s yo'r !re%erence, don0t %ee$ bad 'sing it5 7o&e*er, this g'ide carries t&o &arnings First, since 1 &rote it %or anyone, 1 %e$t com!e$$ed to go into 9'ite a bit o% detai$, &hich yo' might %ind tedio's (i5e5 this s'c,er0s :O;8<+5 Second, in s!ite o% being so $ong, this sti$$ isn0t in any &ay an act'a$ g'ide to )a*ascri!t, the -O/, or creating e#tensions5 Your Task: 6o'r tas, is sim!$y to &rite an e#tension %or 8oog$e Chrome that adds a conte#t men' (a 0right3c$ic, men'0+ to a$$ &eb!ages that $ets yo' har*est and organi=e a$$ o% the $in,s (a anchor tags &ith an href com!onent+ to dis!$ay them in a bo# that0s been added to the to!3right corner o% the doc'ment5 "he 'ser m'st be ab$e to c$ic, to re3sort the $in,s based on $e#icogra!hic order (both ascending and descending+, or based on the $ength o% the $in,s (again, both ascending and descending+5 "he 'ser sho'$d a$so be ab$e to dismiss the bo#5
Background: >eca$$ %or a moment the Comparable inter%ace in )a*a, &hich indicates that a c$ass may be !$aced into a tota$ ordering5 Or, more e#!$icit$y, an instance o% that c$ass, &hen !resented &ith another instance o% the same ty!e, can indicate &hich instance sho'$d !recede the other according to the ordering (or that they ha*e e9'i*a$ent ran,ing+5 "ho'gh Comparable is indeed *ery 'se%'$, it sti$$ has one *ery ob*io's $imitation it can on$y im!ose a sing$e ordering onto its members5 For contrast, $et0s $oo, at a hy!othetica$ sit'ation 6o' ha*e a database o% anima$s, &ith each anima$ ha*ing both a name and an a*erage &eight5 1% an Anima$ c$ass &ere to im!$ement the Comparable inter%ace, then yo'0d on$y be ab$e to im!ose one ordering5 "hat ordering co'$d be based on the a$!habetica$ order o% the names, the &eights, or co'$d e*en consider both (e5g5 sort %irst by &eights, and 'se $e#icogra!hic se9'ence to brea, ties+, b't yo'0d sti$$ ha*e to choose one se9'ence and stic, &ith it5 ?'t &hat i% yo' &ant to sort by &eight %or some circ'mstances and a$!habetica$ order %or others@ Comparable sim!$y does not !ermit this5 )a*a does, ho&e*er, !ro*ide another inter%ace Comparator (!art o% the java.util !ac,age+5 A Comparator is a se!arate too$ that, &hen !resented &ith t&o e$ements, &i$$ com!are them to gi*e yo' an ordering5 Ostensib$y, it so'nds identica$ to Comparable, b't &ith the tedi'm o% ha*ing to dea$ &ith a se!arate %i$e, right@ Ah, b't the catch is yo' can 'se one Comparator %or one ordering, and another Comparator %or a di%%erent ordering for the same elements5 "h's, in o'r anima$ e#am!$e, &e co'$d ha*e a LexiComparator and a HeftComparator5 >e%er to the )a*a AP1 s!eci%ications %or additiona$ detai$s on Com!arators5 So, that0s &hat &e0re going to be doing %or this assignment, right@ 555 right@ 4rm, no!e5 1nstead, &e0re going to be ma,ing 'se o% the e#act same !rinci!$e, b't %or a di%%erent $ang'age and 'se5 JavaScript 6o'0*e a$most certain$y heard o% )a*ascri!t, a $ang'age !rimari$y (tho'gh not e#c$'si*e$y+ 'sed %or c$ient3side scri!ts2 o%ten in &eb!ages5 )a*ascri!t has a rob'st %eat're set that !ro*ides he$!%'$ and e#tensib$e too$s to de*e$o!ers5 (b$ah b$ah b$ah it0s got a $ot o% neat tric,s to %aci$itate being $a=y &oot<+ For e#am!$e, its arrays ha*e se*era$ handy3dandy b'i$t3in %'nctions, inc$'ding a sort5 1% yo' ha*e an array o% *a$'es &ith a nat'ra$ ordering, yo' can sim!$y in*o,e its sort(+ %'nction to rearrange its e$ements5 e5g5 var mice=Array('Pinky','rain','!ichar" #immon$'%& mice.$ort(%& "hat &as555 !retty easy, right@ 7o&e*er, in this case, it0$$ sort a$!habetica$$y ('(rain(,(Pinky(,(!ichar" #immon$()+5 Ahat i% &e don0t &ant that@ Ahat i% &e &ant to sort by string $ength (and, &hi$e &e0re being tric,y, in descending order+@ ;o& there0s a stic,y &ic,et, innit@ Ae$$, &e could .'st do e*erything man'a$$y, b't, again, &e0re ass'ming that B$ess &or,BCBgood &or,B (tho'gh remar,ab$y c$ose to $a=iness, sim!$i%ying yo'r tas, and ma,ing 'se o% inc$'ded too$s does tend to red'ce the chance %or errors+5 "he creators o% )a*ascri!t tho'ght o% that, and they inc$'ded an o!tiona$ !arameter &here yo' can !ass in a com!arator %'nction5 &ait555 did 1 .'st say that yo' can !ass a FD;C"1O; as a PA>A/4"4>@ "7A"0S >1-O;ED:ODS< Act'a$$y, &e0$$ be $earning $ater on that se*era$ $ang'ages can do this5 1n this case, it0s most$y beca'se )a*ascri!t doesn0t care &hat a *ariab$e !oints to (&itho't getting into nitty gritty detai$s, yo' can most$y thin, o% e*erything in )a*ascri!t as being a !ec'$iar Ob.ect2 &ith some sim!$y being better at their identity than others5 "hin, o% it this &ay and it isn0t rea$$y m'ch o% a stretch+5 So, %irst, &e sho'$d $earn ho& to &rite a %'nction in )a*ascri!t, sho'$dn0t &e@ function "o#omethin*(% + alert('ho,"y-'%& . A %e& things to note 15 1% yo'0re ty!ing this man'a$$y into the conso$e, yo' don0t &ant to hit 04nter0 a%ter each $ine5 7it 0Shi%t3 4nter0 instead5 "hat $ets it ,no& that yo'0re sti$$ ty!ing things o't5 Ahen yo'0re done, FthenF hit 04nter05 25 ;ote that 10m inconsistent %or ho& 1 mar, the bo'ndaries o% strings5 Sometimes 1 'se a!ostro!hes2 othertimes 9'otation mar,s5 "hat0s beca'se .a*ascri!t is .'st %ine &ith either5 10m s're yo' can see reasons %or either (e5g5 'sing 9'otation mar,s &hen the string itse$% contains an a!ostro!he, or *ice3 *ersa+5 1% yo' $i,e, yo' can esca!e characters .'st $i,e in )a*a (i5e5 04ar$G0s a&esome, eh@0+5 H5 "he 0a$ert0 %'nction is a handy &ay to ma,e a !o!3'! to dis!$ay a string5 ?e es!ecia$$y care%'$ !'tting it into $oo!s5 45 Ahen yo' ty!e that in, yo' then see 0'nde%ined05 "his is beca'se, &hen there0s a ret'rn %rom an e#!ression, it o't!'ts it into the conso$e (%ee$ %ree to !$ay aro'nd &ith that, or as, me abo't it+5 Simi$ar$y, i% yo' e*er %orget the contents o% a *ariab$e, yo' can sim!$y ty!e its name to see the res'$t (e5g5 ty!ing 0mice20 &i$$ sho& yo' the contents o% the array, i% yo' &ere %o$$o&ing a$ong+5 O,ay, so that0s a$$ &e$$ and good, b't &e ha*en0t tried it o't yet5 :et0s, sha$$ &e@ "o#omethin*(%& (Are yo' im!ressed yet@ ;o@ -ernit+ "ry ty!ing 0"o#omethin*.0, and then $oo,ing at the conte#t men' that !o!s '!5 6o'0$$ see that %'nctions ha*e se*era$ b'i$t3in !ro!erties (inc$'ding a to#trin*(% %'nction< &hich555 a$so has a to#trin*(% %'nction555 10d ma,e a 0%'ncce!tion0 .o,e, b't 1 thin, 10d !re%er to !oint o't that &e heard yo' $i,ed %'nctions in yo'r %'nctions, so &e !'t a %'nction in yo'r %'nction in yo'r %'nction so yo' can555 555 mo*ing on555+5 Additiona$$y, yo' can assign that %'nction to a *ariab$e5 e5g5 var monkey="o#omethin*& (by the &ay, yes, 1 rea$i=e the 0var0 hasn0t been necessary %or these e#am!$es5 "o a*oid a $ong, ramb$ing diatribe on sco!e and com!atibi$ity and s'ch, can yo' .'st h'mo'r me and ,ee! 'sing 0var0 to dec$are *ariab$es@+ 8reat, b't no& o'r %'nction is a *ariab$e, so ho& do &e r'n it@ )'st $i,e the origina$ monkey(%& So, yo' might be &ondering &hat the !oint is, yes@ Ae$$, remember that 1 said yo'0d be !assing a %'nction in as a !arameter2 this is to start to sho& yo' ho& the sort %'nction can ma,e 'se o% it5 7o&0s abo't &e ma,e that com!arator &e &ere ta$,ing abo't@ One that $ets 's sort by $ength, descending@ function "imini$hin*!eturn$(a,b% + return a.len*th==b.len*th/01a.len*th2b.len*th/3414& . (6o' had to ,no& 1 &as going to thro& in those irritating ternary conditiona$ o!erators, right@+ 1% yo' don0t $i,e ho& 'nreadab$e that is, here0s an e9'i*a$ent a$ternati*e function "r(a,b% + if (a.len*th==b.len*th% return 0& if (a.len*th2b.len*th% return 34& return 4& . :et0s test it o't5 Ae co'$d 'se a$ert (and, $et0s %ace it, the &or$d co'$d 'se more $erts+, b't there0s rea$$y no need "r((abba(,(bab(%& sho'$d gi*e 315 "r((abb(,(bab(%& sho'$d gi*e 05 "r((ab(,(bab(%& sho'$d gi*e 15 (1% that seems s$ight$y bac,&ards, remember that &e 'se a negati*e *a$'e to indicate that the %irst !arameter sho'$d precede the second !arameter, etc5+ So, remember o'r mice@ var mice=Array('Pinky','rain','!ichar" #immon$'%& mice.$ort("r%& ;ote that &e get it in order o% $ength, descending, .'st as &e &anted5 A$so note that BPin,yB is sti$$ be%ore B?rainB, as it &as in the origina$5 10d $o*e to be ab$e to te$$ yo' that )a*ascri!t on$y 'ses stab$e sorts, b't 'n%ort'nate$y that *aries by im!$ementation5 Chrome0s, %or e#am!$e, 'n%ort'nate$y, does not (&e$$, it both does and does, i% yo'0re %ami$iar &ith methods o% s!eeding '! I'ic,Sort *ia 1nsertion Sort %or sma$$ cases, b't short *ersion not stab$e+5 Dn%ort'nate$y, this means that, 'n$ess &e &rite o'r o&n (stab$e+ sorting %'nction, &e can0t do subsorts5 Anyhoo, it sho'$d be easy by no& to see ho& !o&er%'$ this is5 Aant to sort by $ength, decreasing@ Pass in a %'nction that does that %or .'st t&o e$ements5 Aant it to sort by $ength, b't ascending@ >e&rite that %'nction, b't &ith %$i!!ed signs5 And, o% co'rse, yo' can come '! &ith a$$ sorts o% other criteria5 1;SA;4 )AJASC>1P" /O/4;" "r.chee$ePreference='!o5uefort'& "imini$hin*!eturn$.chee$ePreference='6arl$ber*'& "here5 /y t&o com!arators no& ha*e !re%erences %or cheese5 alert("r.chee$ePreference%& 6'!5 -e%inite$y does5 (Ahy is this remote$y he$!%'$@ 1% yo' do e*er get interested in com!$icated, 0rea$0 )a*ascri!t &or,, then it can be he$!%'$ %or a$$ sorts o% things5 >e%er to the inc$'ded re%erence %or Ad*anced )a*aScri!t to see e#am!$es $i,e caching res'$ts o% !re*io's %'nction ca$$s to s!eed '! %'t're in*ocations+ RECAP !idcap"# O,ay, so no& &e ,no& a smidgen abo't )a*ascri!t5 ?'t ho& does that he$! 's &ith o'r tas,@ O'r remaining t&o big concerns are ma,ing a Chrome 4#tension and ana$y=ingKmani!'$ating a &eb!age5 Since it0s re$ati*e$y !oint$ess to try ma,ing an 4#tension that doesn0t do anything yet, $et0s mo*e on to the $atter5 7"/: doc'ments ha*e e*o$*ed 9'ite a bit o*er the years (or, !ossib$y more im!ortant$y, o'r re!resentations o% them ha*e+5 :oad '! a &eb!age, right3c$ic, and choose 01ns!ect 4$ement0 again5 -e!ending on &here yo' c$ic,ed, the ins!ector &i$$ .'m! to a corres!onding $ocation in the doc'ment5 ?'t notice that it0s sho&ing a hierarchy5 Ahat0s more, yo' can co$$a!se and e#!and e$ements to seeKhide their contents5 An ordered $ist (ol+, %or e#am!$e, &i$$ ha*e a$$ o% the $ist items (li+ !$aced at higher de!th in the tree, o%% o% the ordered $ist5 Co$$a!se the $ist, and a$$ o% the items get hidden5 (Side note 1% yo' ho*er yo'r c'rsor o*er di%%erent e$ements, Chrome sho'$d shade their corres!onding items in the act'a$ &eb doc'ment5 1% yo' c$ic, on an e$ement in the ins!ector and hit 0de$ete0, yo' can remo*e items %rom the !age5 1t0s $i,e a cra!tac'$ar Ad?$oc,<+ "his is &hat &e ca$$ a -O/ tree (-O/C-oc'ment Ob.ect /ode$+5 1 mention this on$y to aid yo'r 8oog$e3F'5 7o& does this he$! 's@ Ae$$, i% yo' aren0t a$ready there, scro$$ to the to! o% the ins!ector5 6o' sho'$d see the htm$ tag that ho$ds the entire doc'ment (note de!ending on the !age yo'0re *ie&ing, and &hether or not it 'ses %rames, yo' might act'a$$y see m'$ti!$e doc'ments, b't ,ee! it sim!$e %or no&+5 1% it isn0t a$ready, e#!and the htm$ tag to see the head and body tags5 "he head is &here yo'0$$ ty!ica$$y see things $i,e the tit$e, $in,s to CSS, etc5 1t isn0t !artic'$ar$y he$!%'$ %or this e#ercise, so $et0s $oo, at the body instead5 "he body is &here &e ha*e the act'a$ dis!$ayab$e content5 1% yo' c$ic, on something and $oo, to the right, yo' sho'$d see the CSS r'$es that a!!$y to that e$ement (both direct$y, and inherited %rom !arent e$ements+5 Ae0$$ !robab$y need to ma,e 'se o% that e*ent'a$$y, b't not yet5 1% yo' scro$$ do&n, yo'0$$ !robab$y e*ent'a$$y see some 0anchor0 tags (7a278a2+5 Anchor tags are 'sed %or se*era$ things2 t&o o% the biggies are $in,s to other !ages (&ith href+, and to mar, destinations %or boo,mar,s (no, not boo,mar,s to !ages2 those $itt$e Ldea$ie tags yo' o%ten see in D>:s+5 (O% co'rse, as mentioned ear$ier, i% yo' &ant to .'m! straight to an anchor tag, yo' can .'st right3c$ic, a $in,, and choose to 01ns!ect 4$ement05 6o' sho'$d be ta,en direct$y to it+ Since o'r %ina$ goa$ is to be ab$e to grab in%ormation abo't a$$ o% these anchors, &e0re going to need an a'tomated &ay o% ins!ecting these anchors5 ?D" "7460>4 A:: OJ4> "74 P:AC4< ;o !rob$em5 ?ac, to o'r )a*ascri!t conso$e555 "ocument& ;otice that it sho&s &hat a!!ears to be a doc'ment, b't555 &ith no contents@ Oh, hey< One o% those co$$a!sey3 e#!andy dea$ies< C$ic, it< :oo, %ami$iar@ )'st %or ha3ha0s, a$so try ty!ing 0"ocument.0 and seeing &hat !o!s '!5 I'ite a bit, eh@ 4*erything %rom !ro!erties, to methods, to e*ent ca$$bac,s (e5g5 onkeypre$$, &hich is triggered &hen yo'555 1 don0t need to e#!$ain this one, right@+5 One sma$$ distinction to note this 0doc'ment0 corres!onds to the entire str'ct're2 not the *isib$e te#t5 ;ote that yo' need to go in a $e*e$ or t&o to see anything interesting5 So, ho& can &e access, say, the htm$ tag &ithin it@ /aybe try this@ "ocument.html& -ernit5 ;o!e5 "hat &asn0t he$!%'$5 Ae$$555 &e said this &as a tree, right@ And this tree has e$ements (or nodes+ that are dee!er in555 Oh< Chi$dren< "ocument.chil"9o"e$& 7ey< Ae got something< ;ote that it0s an array o% one or more e$ements< (For mine, it0s a -OC"6P4, some commented3o't detai$s, and then the htm$ s'btree+ 1% yo'r htm$ tag ha!!ens to be the %irst chi$d, yo' co'$d .'st say "ocument.fir$tChil"& And yo' can get the second chi$d th's$y "ocument.fir$tChil".next#iblin*& 7o&e*er, $i,e 1 said, the chi$dren are in an array5 So, %or me, 1 needed the third chi$d "ocument.chil"9o"e$':)& ;o&, de!ending on &hat 1 &anted to do, 1 co'$d do a $ot o% interesting things by %o$$o&ing these $in,s %'rther and %'rther (changing beha*io'rs, addingKremo*ing e$ements, changing CSS, etc5+5 "o ma,e things sim!$er, 1 might ma,e *ariab$es to mar, im!ortant s'btrees5 For e#am!$e, %or the !age 1 ha!!ened to be *ie&ing var bo"y="ocument.chil"9o"e$':).chil"9o"e$':)& ?'t there0s a !rob$em, isn0t there@ "his is a$$ %ine and good %or doing e*erything man'a$$y, b't there0s no &ay any o% that code co'$d be a!!ro!riate %or genera$ 'se5 7ec,, 1 do'bt it &o'$d ma,e m'ch sense %or the !ages ha$% o% the c$ass ha!!ened to choose to test on< ?'t that0s o,ay5 1n this case, &e0re $oo,ing %or something *ery s!eci%ic, aren0t &e@ 1t might not seem s!eci%ic (a%ter a$$, &e don0t ,no& ho& many anchor tags there0$$ be, &hat they0$$ contain, etc5+, b't &e specifically &ant to a!!$y some sort o% beha*io'r on each anchor tag5 "his means that, &ere &e to ha*e some sort o% data str'ct're containing only anchor tags, &e co'$d *ery easi$y do some ins!ectionKmani!'$ation (yes, 1 rea$i=e &e co'$d a$so &rite an a$gorithm that man'a$$y tra*ersed each branch instead, b't note the ,ey &ord, Beasi$yB+5 Ae$$, &e0re in $'c,, beca'se o'r doc'ment ob.ect has m'$ti!$e %'nctions %or that sort o% 'se< "ry .'st ty!ing 0"ocument.*et0, and seeing the s'ggestions5 Ae co'$d grab a !artic'$ar e$ement based on its 0i"0 (i"0s are supposed to be 'ni9'e in each doc'ment, so they don0t inc$'de a %'nction %or grabbing a$$ o% them &ith the same id+2 that0s neat, and genera$$y he$!%'$ %or Chrome e#tensions, b't $ess3he$!%'$ %or &hat &e &ant5 Ooh, &hat0s this@ "ocument.*et;lement$by<a*9ame (there0s a$so a *et;lement$y<a*9ame9#, b't that0s %or searching &ithin !artic'$ar names!aces2 it0s neat, b't not immediate$y 'se%'$+5 :et0s try it o't< "ocument.*et;lement$y<a*9ame((a(%& Ahoa< -e!ending on the !age yo' chose, that co'$d be 9'ite a %e&, eh@ :et0s try hanging onto those %or a moment var allAnchor$="ocument.*et;lement$y<a*9ame((a(%& "hat certain$y seems handy, eh@ Dn%ort'nate$y, de!ending on the !age yo' chose, yo' might ha*e some anchors that aren0t rea$$y $in,s to other !ages (e5g5 'sed %or boo,mar,s+5 "he on$y ones &e &ant are those &ith href tags5 "his is !robab$y a good time to mention something5 a$$Anchors isn0t act'a$$y an array5 Ae can access its contents $i,e one, b't it isn0t rea$$y one (1 m'dd$ed the terms a bit abo*e, to a*oid thro&ing too many things at once at yo'+5 allAnchor$ is an ob.ect, b't not an array5 Ahat0s the di%%erence@ Ae$$, %irst o%%, &e can0t sort it5 ?D" 7OA A>4 A4 8O1;8 "O ?4 A?:4 "O DS4 CO/PA>A"O>S@<@<@ "here are t&o a!!roaches5 "he e$egant a!!roach &o'$d be to man'a$$y in*o,e Array0s s$ice %'nction on the ob.ect, &hich co'$d certain$y create the necessary array5 7o&e*er, &e0d sti$$ ha*e the !rob$em that some e$ements aren0t act'a$$y $in,s (e*en i% this isn0t the case %or yo'r test doc'ment, &e sti$$ can0t ass'me that0$$ a$&ays be tr'e+5 So, $et0s do this o$d3schoo$ and ,i$$ t&o birds &ith one stone, eh@ var linkAnchor$=Array(%& for (var i=0&i7allAnchor$.len*th&i==% + if (allAnchor$'i).href% linkAnchor$.pu$h(allAnchor$'i)%& . ;o&, i% &e $oo, at linkAnchor$, &e0$$ see that it can do e*erything an array can do and it on$y contains those anchors that had $in,s< Ae0re certain$y getting c$oser5 (?y the &ay, .'st as an aside, i% yo'0d $i,e an e#am!$e o% a !age &ith anchors that don0t ha*e $in,s, chec, this o't htt!KKdocs5orac$e5comK.a*aseKMKdocsKa!iK.a*aK'ti$KCom!arator5htm$ + As a %ina$ tho'ght be%ore &e contin'e, &e might &ant to %i$ter o't e*en more $in,s5 Some $in,s might not ha*e any te#t at a$$ (e5g5 %or b'ttons+, some might or might not ha*e tit$es, etc5 For this e#ercise, 10d s'ggest .'st acce!ting that some o% o'r res'$ts might $oo, mi$d$y si$$y5 ;o&, a$$ &e need to do is to sort them5 So, ho& do &e sort@ Ae can start by, say, ascending $ength o% $in, addresses (hre%+@ :et0s &rite a com!arator function href#i>eA$c(a, b% + return a.href.len*th==b.href.len*th/01a.href.len*th7b.href.len*th/3414& . ;otice that 10m no& starting to 'se more he$!%'$ names %or things5 "hat0s beca'se &e0re getting c$oser to the %ina$ !rod'ct5 )'st to *eri%y that it &or,s linkAnchor$.$ort(href#i>eA$c%& "y!ing linkAnchor$'0).href& %o$$o&ed by linkAnchor$'4).href& sho'$d sho& that the second $in, is $onger than (or e9'a$ in $ength to+ the %irst $in,5 So, no& &e ha*e an array o% $in,s5 1t might not seem as tho'gh &e0*e accom!$ished m'ch, b't &e rea$$y ha*e5 For the sa,e o% not ha*ing to $oo, aro'nd to co!yN!aste, $et0s .'st assemb$e e*erything &e ha*e so %ar together function href#i>eA$c(a, b% + return a.href.len*th==b.href.len*th/01a.href.len*th7b.href.len*th/3414& . function *rabLink$?romPa*e(% + var allAnchor$="ocument.*et;lement$y<a*9ame((a(%& var linkAnchor$=Array(%& for (var i=0&i7allAnchor$.len*th&i==% + if (allAnchor$'i).href% linkAnchor$.pu$h(allAnchor$'i)%& . linkAnchor$.$ort(href#i>eA$c%& return linkAnchor$& . "ry $oading '! a di%%erent !age, entering a$$ o% that into the conso$e, and then testing it o't var anchor$=*rabLink$?romPa*e(%& Ae co'$d choose a di%%erent sorting criteria no& (e5g5 a$!habetica$ order, based on an anchors .inner<ext+, b't $et0s mo*e on to the ne#t ste!5 >emember ho& &e said &e can add e$ements to the doc'ment@ Ae$$, $et0s do that< var anchorox="ocument.create;lement((@AB(%& "ocument.bo"y.appen"Chil"(anchorox%& anchorox.inner<ext='hi'& Scro$$ do&n to the bottom o% the !age, and yo' sho'$d see yo'r ne& bo#5 1t &on0t $oo, *ery bo#y yet2 it0s .'st the te#t, 0hi05 First things %irst, $et0s mo*e it '! to the to! o% the !age5 Since &e0re no& ta$,ing abo't $ayo't, sty$e seems to be the ob*io's thing to modi%y5 1% yo' ty!e 0anchorox.$tyle.0 and $oo, at the o!tions, yo'0$$ see that there are 9'ite a %e&5 :'c,i$y, &e don0t need *ery many o% them5 (AA>;1;8< AA>;1;8< "o any &eb de*e$o!ers in the c$ass, this is going to be teeerrib$e< Ae0re going %or Bget0er doneB, not B%o$$o& the standards !er%ect$y to !resent a mod'$ar and com!$iant im!$ementationB+ anchorox.$tyle.>An"ex='4000'& anchorox.$tyle.top='0px'& anchorox.$tyle.ri*ht='0px'& anchorox.$tyle.po$ition='ab$olute'& Scro$$ to the to!, and yo' sho'$d see a $itt$e 0hi0 in the '!!er3right corner5 ;ote, i% &e chosed a !osition o% 0%i#ed0 instead o% 0abso$'te0, then it &o'$d Fa$&aysF be in the '!!er3right corner (i5e5 it &o'$dn0t scro$$ &ith the doc'ment+5 "hat co'$d !otentia$$y be neat, b't &o'$d get irritating %ast i% there &ere more $ines o% $in,s than co'$d %it on a sing$e !age5 var link<able="ocument.create;lement((<AL;(%& link<able.i"='tooPea9inety'& anchorox.appen"Chil"(link<able%& anchorox& ;ote that $ast $ine is .'st to ins!ect the c'rrent state o% o'r @AB5 ;ote that &e can see the te#t, %o$$o&ed by the tab$e (&e don0t see the tab$e on the !age yet beca'se it sti$$ doesn0t ha*e anything inside it+5 :et0s sidetrac, %or a moment .'st to *eri%y that &e0re rea$$y doing anything var te$t="ocument.create;lement((<!(%& link<able.appen"Chil"(te$t%& te$t.appen"Chil"("ocument.create;lement((<@(%%& te$t.fir$tChil".inner<ext=(Hello-(& 6o' sho'$d see the te#t no&5 ;ote that it0s entire$y !ossib$e ($i,e$y+ that the 0tab$e0 &on0t act'a$$y ha*e a border5 ;o&0s as good a time as any to remedy that link<able.$tyle.bor"er#tyle='$oli"'& link<able.$tyle.bor"erCi"th='4px'& link<able.$tyle.bor"erColor='black'& link<able.$tyle.back*roun"Color=',hite'& "here &e go< At $east no& it0s a bo#, &hich is ,inda sorta *ag'e$y tab$e3y< Since &e no& ha*e an act'a$ tab$e to &or, on, that 0hi0 isn0t rea$$y he$!%'$5 :et0s remo*e it anchorox.removeChil"(anchorox.fir$tChil"%& 1% yo' aren0t %ami$iar &ith 7"/:, <! stands %or 0"ab$e >o&0, and <@ stands %or 0"ab$e -Ce$$, b't the - is si$ent0 (Act'a$$y, it stands %or 0"ab$e -ata0, b't 1 $i,e mine better+5 So, &e ,no& ho& to add ro&s to the tab$e, and &e ,no& ho& to add ce$$s to a ro&5 "heoretica$$y, &e sho'$d no& ha*e a$$ o% the too$s &e need to a'tomagica$$y insert entries into the tab$e %rom an array5 O% co'rse, &e sho'$d %irst !robab$y remo*e o'r test &or, link<able.removeChil"(link<able.fir$tChil"%& "his is &here yo' try &riting it yo'rse$%, and 1 do the same, and &e com!are res'$ts5 (;o !ee,ing<+ 6o'0re done@ 8reat< :et0s com!are< 7ere0s &hat 1 ha*e function appen"Link(tar*et,anchor% + var ro,=tar*et.in$ert!o,(34%& var cell=ro,.in$ertCell(34%& cell.innerH<DL=(7a href='(=anchor.href=('2(=(anchor.href.len*th2E:/ anchor.href.$ub$trin*(0,E0%=(...(1anchor.href%=(78a2(& var cell=ro,.in$ertCell(34%& cell.inner<ext=anchor.title/anchor.title1anchor.inner<ext/anchor.inner<ext1 (anchor.href.len*th2E:/anchor.href.$ub$trin*(0,E0%=(...(1anchor.href%& . function populate<able(tar*et,element$% + for (var i=0&i7element$.len*th&i==% + appen"Link(tar*et,element$'i)%& . . populate<able(link<able,anchor$%& (;ote that 1 tended to $imit the $engths o% dis!$ayed strings5 "his &as arg'ab$y 'nnecessary, b't does sti$$ !re*ent the ro& &idths %rom getting terrib$y $ong+ So, &e ha*e no& %ig'red o't ho& to retrie*e a$$ o% the anchors, sort them according to some (re!$aceab$e+ com!arator, and insert a re!ort o% the res'$t into the doc'ment5 "his is !robab$y a good time to !oint o't that the sty$e o% the so'rce !age &i$$ be inherited by the com!onents5 "hat is, i% the !age yo'0re ana$y=ing has a si$$y %ont, then yo'r ne& tab$e may a$so ha*e a si$$y %ont5 "he same goes %or co$o'r, etc5 An easy so$'tion &o'$d be to change the sty$e o% each e$ement as yo'0re adding them5 6o' can e*en set their sty$e attrib'tes to 0initia$0 to re*ert to &hate*er the 0de%a'$t0 sty$e &o'$d ha*e other&ise been, i% yo' don0t &ant to choose one o% yo'r o&n5 10$$ $ea*e it '! to yo' to decide i% yo' &ish to do this or not5 "he ne#t ste! sho'$d !robab$y be to &rite the other com!arators function href#i>e@e$c(a, b% + return a.href.len*th==b.href.len*th/01a.href.len*th2b.href.len*th/3414& . function lexicoA$c(a,b% + var a<ext=a.title/a.title1a.inner<ext/a.inner<ext1a.href& var b<ext=b.title/b.title1b.inner<ext/b.inner<ext1b.href& return a<ext==b<ext/01a<ext7b<ext/3414& . function lexico@e$c(a,b% + var a<ext=a.title/a.title1a.inner<ext/a.inner<ext1a.href& var b<ext=b.title/b.title1b.inner<ext/b.inner<ext1b.href& return a<ext==b<ext/01a<ext2b<ext/3414& . If yo'0*e been %o$$o&ing a$ong ste!3by3ste!, then instead o% ha*ing to re$oad and re3enter a$$ o% the code, yo' can sim!$y test this &ay anchor$.$ort(lexico@e$c%& link<able.innerH<DL=null& 88(or (( or ''% populate<able(link<able,anchor$%& Ae0re ma,ing some great !rogress here5 ?'t &e0d sti$$ $i,e to be ab$e to re3sort &itho't ha*ing to man'a$$y c$ear it o't and in*o,e it5 O% co'rse, considering ho& sim!$e it is to do it man'a$$y, &e can be !retty con%ident that it &on0t be terrib$y di%%ic'$t to a'tomate it, either5 1% &e &anted, &e co'$d add a header to the tab$e (there are se*era$ easy &ays to do this+5 7o&e*er, since &e0d then ha*e to dea$ &ith merging ce$$s to ,ee! e*erything $ined '! and s'ch555 &hy not .'st add something be%ore the tab$e itse$%@ var lexA$cutton="ocument.create;lement((#PA9(%& var lex@e$cutton="ocument.create;lement((#PA9(%& var len*thA$cutton="ocument.create;lement((#PA9(%& var len*th@e$cutton="ocument.create;lement((#PA9(%& lexA$cutton.$tyle.color=lex@e$cutton.$tyle.color=len*thA$cutton.$tyle.color =len*th@e$cutton.$tyle.color='li*ht*reen'& lexA$cutton.$tyle.back*roun"Color =lex@e$cutton.$tyle.back*roun"Color=len*thA$cutton.$tyle.back*roun"Color =len*th@e$cutton.$tyle.back*roun"Color='black'& lexA$cutton.$tyle.mar*in=lex@e$cutton.$tyle.mar*in =len*thA$cutton.$tyle.mar*in=len*th@e$cutton.$tyle.mar*in='Fpx'& lexA$cutton.inner<ext='Alphabetic A#C'& lex@e$cutton.inner<ext='Alphabetic @;#C'& len*thA$cutton.inner<ext='Len*th A#C'& len*th@e$cutton.inner<ext='Len*th @;#C'& anchorox.in$ertefore(lexA$cutton,link<able%& anchorox.in$ertefore(lex@e$cutton,link<able%& anchorox.in$ertefore(len*thA$cutton,link<able%& anchorox.in$ertefore(len*th@e$cutton,link<able%& ;o&, 1 thin, 1 ,no& &hat yo'0re thin,ing B?'t, 4ar$, that0s b'tt3'g$y<B Ahy yes5 6es, it is5 6o'0re &e$come to do better5 "his is a demonstration, not a design c$ass5 Ahat &e &ant to be ab$e to do is to c$ic, one o% those b'ttons and ha*e it a'tomatica$$y re3sort the $ist5 ;ote that, since &e a$&ays retain an array o% the act'a$ data, there0s rea$$y no need to hang onto any e$ements o% the tab$e itse$% bet&een sortings, so &e0$$ .'st be dro!!ing the tab$e0s contents each time (.'st as &e did &ith the sam!$e code abo*e+5 "hose b'ttons are going to trigger that code, b't to do so &e0$$ need to ma,e 'se o% events5 1n this case, 0onclick0 e*ents5 ?e%ore &e get to the rea$ attem!t lexA$cutton.onclick=function(%+alert('hi'%&.& ;o&, &hene*er &e c$ic, on the BA$!habetic ASCB b'tton, it &i$$ e#ec'te that Banonymo's %'nctionB to generate a mi$d$y annoying !o!'!< 4*en tho'gh the code %or resetting is on$y three $ines $ong, 10d sti$$ %ee$ more com%ortab$e t'rning it into a %'nction function re$ort<able(anchor$,table,comparator% + anchor$.$ort(comparator%& table.innerH<DL=null& populate<able(table,anchor$%& . lexA$cutton.onclick=function(%+re$ort<able(anchor$,link<able,lexicoA$c%&.& "here0s sti$$ a missing e$ement here2 something basic5 Choosing to dis!$ay a$$ o% the $in,s on a !age doesn0t mean yo'0re necessari$y done &ith that !age yet5 7o&e*er, once the $in,s are dis!$ayed, there0s no con*enient method o% dismissing the bo#5 "his is act'a$$y !retty easy to do5 7o& do yo' norma$$y c$ose a &indo& in ty!ica$ so%t&are@ Aith the c$ose b'tton< So, &hy not .'st add a c$ose b'tton@ var clo$eutton="ocument.create;lement((#PA9(%& clo$eutton.$tyle.color='li*ht*reen'& clo$eutton.$tyle.back*roun"Color='black'& clo$eutton.$tyle.mar*in='Fpx'& clo$eutton.$tyle.ri*ht='0px'& clo$eutton.$tyle.po$ition='ab$olute'& clo$eutton.inner<ext='G'& anchorox.in$ertefore(clo$eutton,link<able%& clo$eutton.onclick=function(%+aboli$hAnchorox(%&.& "here &e go< A bit basic, b't it &or,s5 7o&e*er, e*en tho'gh &e can do &hat &e &ant no&, there0s sti$$ one s$ight 9'ir, &ith the %'nctiona$ity5 "ry dis!$aying the bo# o% $in,s, and then try doing it again5 i5e5 try r'nning the scri!t t&ice in a ro&5 Ae end '! &ith t&o bo#es, &ith one o% those bo#es being t&ice the si=e (&hich isn0t s'r!rising, since it a$so har*ested $in,s %rom the !re*io's !o!'! bo#+5 "his one0s incredib$y easy to %i#5 ;otice that, %or the $ast !art, &e &rote a %'nction that on$y tries to remo*e the bo# i% it0s rea$$y there@ Einda odd &ay to !hrase it, since &e &ere ha*ing it triggered by a c$ose b'tton on the bo# (that is, ho& co'$d it not be there, i% it &as necessary %or r'nning it@+5 "hat &as act'a$$y !hrased that &ay %or this !art5 "he so$'tion is sim!$e ?e%ore doing anything e$se %or the code, sim!$y r'n that %'nction5 1% this is the %irst e#ec'tion (i5e5 there isn0t a$ready a bo# o% $in,s '!+, then it sim!$y &on0t do anything5 1% yo' grab a$$ o% the !ieces &e had abo*e (ignoring things $i,e adding 0hi0 and other things &e 'ndid+, yo'0$$ see that &e act'a$$y ha*e s'%%icient code %or a &or,ing so$'tion5 1n %act, it0d !robab$y $oo, something $i,e this (more or $ess+ 88Cleanup function aboli$hAnchorox(% + if ("ocument.*et;lementyA"('tooPea9inety'%% + "ocument.bo"y.removeChil"("ocument.*et;lementyA"((tooPea9inety(% .parent9o"e%& . . aboli$hAnchorox(%& 88===CHDPA!A<H!#===88 function href#i>eA$c(a, b% + return a.href.len*th==b.href.len*th/01a.href.len*th7b.href.len*th/3414& . function href#i>e@e$c(a, b% + return a.href.len*th==b.href.len*th/01a.href.len*th2b.href.len*th/3414& . function lexicoA$c(a,b% + var a<ext=a.title/a.title1a.inner<ext/a.inner<ext1a.href& var b<ext=b.title/b.title1b.inner<ext/b.inner<ext1b.href& return a<ext==b<ext/01a<ext7b<ext/3414& . function lexico@e$c(a,b% + var a<ext=a.title/a.title1a.inner<ext/a.inner<ext1a.href& var b<ext=b.title/b.title1b.inner<ext/b.inner<ext1b.href& return a<ext==b<ext/01a<ext2b<ext/3414& . 88===;9@ CHDPA!A<H!#===88 function *rabLink$?romPa*e(% + var allAnchor$="ocument.*et;lement$y<a*9ame((a(%& var linkAnchor$=Array(%& for (var i=0&i7allAnchor$.len*th&i==% + if (allAnchor$'i).href% linkAnchor$.pu$h(allAnchor$'i)%& . linkAnchor$.$ort(href#i>eA$c%& return linkAnchor$& . var anchor$=*rabLink$?romPa*e(%& var anchorox="ocument.create;lement((@AB(%& "ocument.bo"y.appen"Chil"(anchorox%& anchorox.$tyle.>An"ex='4000'& anchorox.$tyle.top='0px'& anchorox.$tyle.ri*ht='0px'& anchorox.$tyle.po$ition='ab$olute'& anchorox.$tyle.back*roun"Color='black'& var link<able="ocument.create;lement((<AL;(%& link<able.i"='tooPea9inety'& anchorox.appen"Chil"(link<able%& link<able.$tyle.bor"er#tyle='$oli"'& link<able.$tyle.bor"erCi"th='4px'& link<able.$tyle.bor"erColor='black'& link<able.$tyle.back*roun"Color=',hite'& function limitLen*th($% + return $.len*th2E:/$.$ub$trin*(0,E0%=(...(1$& . 88A""$ a $in*le anchor'$ entry to a tar*et table function appen"Link(tar*et,anchor% + var ro,=tar*et.in$ert!o,(34%& var cell=ro,.in$ertCell(34%& cell.innerH<DL=(7a href='(=anchor.href=('2(=limitLen*th(anchor.href%=(78a2(& var cell=ro,.in$ertCell(34%& cell.inner<ext=anchor.title/limitLen*th(anchor.title%1 anchor.inner<ext/limitLen*th(anchor.inner<ext%1limitLen*th(anchor.href%& . 88Populate$ a $pecifie" table (tar*et% ,ith element$ (element$% function populate<able(tar*et,element$% + for (var i=0&i7element$.len*th&i==% + appen"Link(tar*et,element$'i)%& . . populate<able(link<able,anchor$%& var lexA$cutton="ocument.create;lement((#PA9(%& var lex@e$cutton="ocument.create;lement((#PA9(%& var len*thA$cutton="ocument.create;lement((#PA9(%& var len*th@e$cutton="ocument.create;lement((#PA9(%& lexA$cutton.$tyle.color=lex@e$cutton.$tyle.color=len*thA$cutton.$tyle.color =len*th@e$cutton.$tyle.color='li*ht*reen'& lexA$cutton.$tyle.back*roun"Color=lex@e$cutton.$tyle.back*roun"Color =len*thA$cutton.$tyle.back*roun"Color =len*th@e$cutton.$tyle.back*roun"Color='black'& lexA$cutton.$tyle.mar*in=lex@e$cutton.$tyle.mar*in =len*thA$cutton.$tyle.mar*in=len*th@e$cutton.$tyle.mar*in='Fpx'& lexA$cutton.inner<ext='Alphabetic A#C'& lex@e$cutton.inner<ext='Alphabetic @;#C'& len*thA$cutton.inner<ext='Len*th A#C'& len*th@e$cutton.inner<ext='Len*th @;#C'& anchorox.in$ertefore(lexA$cutton,link<able%& anchorox.in$ertefore(lex@e$cutton,link<able%& anchorox.in$ertefore(len*thA$cutton,link<able%& anchorox.in$ertefore(len*th@e$cutton,link<able%& var clo$eutton="ocument.create;lement((#PA9(%& clo$eutton.$tyle.color='li*ht*reen'& clo$eutton.$tyle.back*roun"Color='black'& clo$eutton.$tyle.mar*in='Fpx'& clo$eutton.$tyle.ri*ht='0px'& clo$eutton.$tyle.po$ition='ab$olute'& clo$eutton.inner<ext='G'& anchorox.in$ertefore(clo$eutton,link<able%& clo$eutton.onclick=function(%+aboli$hAnchorox(%&.& function re$ort<able(anchor$,table,comparator% + anchor$.$ort(comparator%& table.innerH<DL=null& populate<able(table,anchor$%& . lexA$cutton.onclick=function(%+re$ort<able(anchor$,link<able,lexicoA$c%&.& lex@e$cutton.onclick=function(%+re$ort<able(anchor$,link<able,lexico@e$c%&.& len*thA$cutton.onclick=function(%+re$ort<able(anchor$,link<able,href#i>eA$c%&.& len*th@e$cutton.onclick=function(% +re$ort<able(anchor$,link<able,href#i>e@e$c%&.& O% co'rse, this sti$$ re9'ires that &e man'a$$y r'n the code on each !age5 "hat0s a !ain, not to mention not o'r goa$5 C$ro!e E%tensions :i,e any bro&ser &orth its sa$t (or sa$t s'bstit'te+, 8oog$e Chrome can easi$y ha*e its %'nctiona$ity e#!anded thro'gh the addition o% e#tensions5 4#tensions may be 'sed %or a great n'mber o% tas,s, %rom modi%ying a !age, to retrie*ing andKor storing reso'rces %rom other !ages, to e*en sim!$e games5 -e!ending on the 'se, there are n'mero's di%%erent &ays to ha*e an e#tension o!erate on or generate !age data5 "hree o% the big ones (that &e !robab$y &on0t be 'sing here+ are Browser Actions, Page Actions, and Content Scripts5 10d strong$y enco'rage yo' to $oo, '! a$$ three o% those, beca'se they0re *ery 'se%'$ %or rea$i=ing &hat yo' can do &ith e#tensions5 1% o'r desired o'tcome &ere on$y min'te$y di%%erent, &e0d !robab$y be 'sing a bro&ser action (&ith a b'tton on the too$bar+ that &o'$d .'st !resent a se!arate !o!'!5 7o&e*er, &e0$$ .'st be ma,ing a conte#t men' item to create a @AB5 Ae0$$ 'se a Background Script to act'a$$y create it, and to de%ine and assign the necessary code to be triggered &hene*er the men' item is chosen5 ?ac,gro'nd Pages and ?ac,gro'nd Scri!ts are a$so things yo' sho'$d consider researching on yo'r o&n, b't, basica$$y, a bac,gro'nd scri!t is something that a'tomatica$$y e#ec'tes, &itho't re9'iring a !age %or conte#t5 1t0s best 'sed %or initia$i=ing connections to the bro&ser0s e$ements, estab$ishing ca$$bac,s, coordinating other com!onents, etc5 6o' are very strong$y enco'raged to re*ie& 8oog$e0s -e*e$o!er t'toria$s %or e#tensions5 7o&e*er, as &ith the !re*io's !arts, yo' can sim!$y %o$$o& a$ong here i% yo' !re%er5 ?e%ore yo' do anything e$se, create a %o$der that &i$$ only contain %i$es %or this e#tension5 Chrome 4#tensions are !retty sim!$e in terms o% their com!onents5 "hey contain their necessary scri!t %i$esK!ages, reso'rces (e5g5 images %or icons+, and a$so &hat0s ,no&n as a manifest5 A mani%est %or an e#tension is *ery simi$ar to a mani%est %or a )a*a 5.ar5 1t most$y .'st doc'ments the e#tension and identi%ies the ro$es o% inc$'ded reso'rces5 :et0s $oo, at a rea$$y sim!$e one + (name( 1 (Contextual#craper(, (ver$ion( 1 (0.0.0.4(, ("e$cription( 1 (Collect ALL <H; LA9I#- from the current pa*e(, (back*roun"( 1 + ($cript$(1 '(back*roun".j$() ., (permi$$ion$( 1 ' (contextDenu$(, (tab$(, (http188J8J(, (http$188J8J( ), (minimumKchromeKver$ion( 1 (L.0.0.0(, (manife$tKver$ion(1 : . "his needs to be in a %i$e ca$$ed manife$t.j$on that needs to be in the %o$der &e created ear$ier5 :et0s $oo, at the indi*id'a$ com!onents here name O "his sho'$d be ob*io's ver$ion O -itto "e$cription O 6o'0$$ see this message &hen managing yo'r e#tensions &ithin Chrome back*roun" O 7ere0s &here &e start &ith the 0rea$0 st'%%5 "here are t&o basic ty!es o% bac,gro'nd item a !age or a scri!t5 A !age can be handy i% yo' need to create a 5htm$ %i$e that can be bro'ght '! $ater5 A scri!t can be 'se%'$ %or registering %or e*ent hand$ers, etc5 permi$$ion$ O Chrome is re$ati*e$y sec'rity3conscio's5 "he basic idea is that $etting an e#tension access content across domains may be a good or bad idea, de!ending on the code, b't that the 'ser is entit$ed to choose &hether or not to $et that ha!!en5 1n this case, &e0re reser*ing the right to mani!'$ate the conte#t men', to access tabs, and to access content on !retty m'ch any &ebsite5 minimumKchromeKver$ion O "his is the n'mber o% !e$icans 1 had %or brea,%ast today5 (serio's$y, this one0s a$so easy to identi%y+ manife$tKver$ion O 1% yo'0re 'sing a recent *ersion o% Chrome (and yo' sho'$d be+, it &on0t $et yo' !ac, an e#tension 'sing an o$der mani%est *ersion (i% yo'0re $earning a$$ o% this %or the %irst time no&, then this doesn0t rea$$y a%%ect yo' m'ch+5 Since &e0*e !romised a scri!t ca$$ed bac,gro'nd5.s, $et0s ma,e that< function *etClickHan"ler(info,tab% + return function(info, tab% + alert('ho,"y'%& .& .& chrome.contextDenu$.create(+ (title( 1 (Lemme $ee the link$e$-(, (type( 1 (normal(, (onclick( 1 *etClickHan"ler(% .%& Ahen &e0re creating o'r conte#t men', note that &e need to both gi*e it something to dis!$ay (its tit$e+, and something to do &hen chosen5 6o' !robab$y don0t need to do it as con*o$'ted as 1 did, b't it rea$$y doesn0t h'rt5 Ahen the 'ser chooses to 0see the $in,ses0, a %'nction is ca$$ed that ret'rns an anonymo's %'nction to be e#ec'ted5 ?e%ore &e get any %'rther, $et0s try this o't (yes, e*en tho'gh &e ,no& it &on0t do anything he$!%'$+5 >emember that yo' sho'$d ha*e a %o$der &ith t&o %i$es manife$t.j$on and back*roun".j$5 :oad '! Chrome (i% yo' ha*en0t a$ready+, choose "oo$s and c$ic, 4#tensions (or sim!$y ty!e 0chromeKKe#tensions0 into the address bar+5 At the to!, to&ards the right, yo' sho'$d see a chec,bo# %or, B-e*e$o!er modeB5 Chec, that bo#5 6o' sho'$d no& be ab$e to B:oad 'n!ac,ed e#tensionB5 C$ic, that and choose the %o$der mentioned abo*e5 ;o&, &hen yo' go to a !age and right3c$ic, the doc'ment, yo' sho'$d be ab$e to see the ne& conte#t men' item5 "ry it o't< 8reat, so &e can de%inite$y e#ec'te scri!t5 ?'t that isn0t the scri!t &e &ant5 Ae could try 'sing the code that &e &rote in the !re*io's section, b't 'n%ort'nate$y that &on0t &or,5 Ahy not@ :et0s ta,e a $oo, function *etClickHan"ler(info,tab% + return function(info, tab% + "ealie(%& .& .& function "ealie(% + alert("ocument.location.href%& . 1% yo' go bac, to the 4#tensions tab, yo' sho'$d notice a sma$$ 0>e$oad0 $in, at the bottom o% yo'r e#tension5 C$ic, that5 ;o&, once again, try choosing the conte#t men' item on some &eb!age5 Dh oh5 "hat0s a !rob$em5 "hat0s &hat it thin,s the doc'ment0s D>: is5 So, i% that0s &hat it thin,s the address is, yo' can !robab$y g'ess that it doesn0t ,no& the contents o% the !age &e &ant, either5 "hat is, since it0s r'nning %rom &ithin the conte#t o% the e#tension, that0s a$so the 0doc'ment0 it0s trying to 'se< Ahat &e need to do is to tric, the rea$ doc'ment into r'nning arbitrary code %or 's5 function *etClickHan"ler(info,tab% + return function(info, tab% + chrome.tab$.execute#cript(tab.i",+ co"e1 '"ealie(%&' .%& .& .& function "ealie(% + alert("ocument.location.href%& . Sa*e, re$oad, etc5 "ry it o't< 555 ah cr'd5 -idn0t &or,, did it@ 1% yo' bring '! the )a*ascri!t conso$e again, yo'0$$ see the !rob$em 1t0s ne*er heard o% dea$ie< ?'t, &ait, this means that, be%ore, &e co'$d r'n the code since it &as in o'r bac,gro'nd scri!t, b't co'$dn0t access the doc'ment beca'se it &as in another conte#t5 ;o&, &e can !robab$y access the doc'ment, b't &e can no $onger access o'r bac,gro'nd scri!t beca'se no& FthatF0s in the other conte#t@ Ah, b't there0s a (*ery $a=y+ so$'tion< function *etClickHan"ler(info,tab% + return function(info, tab% + chrome.tab$.execute#cript(tab.i",+ co"e1 '"ealie='="ealie='&"ealie(%&' .%& .& .& function "ealie(% + alert("ocument.location.href%& . "here &e go< ;o& &e can in.ect code &e &ant, to be e#ec'ted in the conte#t &e &ant< So, instead o% 0"ealie0, choose something more a!!ro!riateKcoo$ (1 chose omni?unc+5 "hen, sim!$y ta,e a$$ o% the code %rom the !re*io's !art, and !$ace it inside that %'nction< (6es, 10m intentiona$$y not sho&ing the %ina$ code, so yo' can0t .'st co!yN!aste %rom the end o% this g'ide &ith no reading at a$$+ ;o& that &e ha*e it a$$ &or,ing, there0s .'st one $ast tri*ia$ ste! $e%t Act'a$$y t'rning it into a distrib'tab$e e#tension5 "his !art0s easy5 On Chrome0s 4#tension !age again, choose BPac, e#tension555B5 For the 4#tension root directory, .'st !ic, the same %o$der yo'0*e been 'sing %or testing5 6o' don0t need to &orry abo't a ,ey5 C$ic, BPac, 4#tensionB, and it sho'$d ha*e created a 5cr# %i$e (the act'a$ e#tension+5 1n my case, it made CithContextDenu.crx5 >emo*eKDninsta$$ the testing *ersion o% yo'r e#tension (c$ic, the garbage can beside it+, and drag the 5cr# %i$e %rom yo'r %i$e bro&ser bac, onto yo'r 4#tension !age5 ;ote that it as,s yo' to con%irm the !ermissions yo'0re granting5 C$ic, Add5 And that0s it< 6o'0re done< Su&!ission: 4$ectronic P't a$$ o% yo'r %i$es into the same %o$der5 Dse this %o$der %or the s'bmission scri!t submit2p90 -on0t %orget to inc$'de the 5cr# %i$e as &e$$< Physica$ "a,e a screenshot o% yo'r &or, in action5 Print o't a$$ o% yo'r code (inc$'ding yo'r mani%est+5 Fi$$ o't a de!artmenta$ co*er %orm and sta!$e it to the %ront5 S'bmit yo'r assignment into the a!!ro!riate de!artmenta$ dro!bo#5 Additional Reading: htt!KK&&&5&Hschoo$s5comK.sre%K htt!KKe.ohn5orgKa!!sK$earnK htt!KKde*e$o!er5chrome5comKe#tensionsKgetstarted5htm$ htt!KKde*e$o!er5chrome5comKe#tensionsKconte#t/en's5htm$ htt!KKhangar5r'n&ayM5netK.a*ascri!tKg'ide htt!KKde*e$o!er5chrome5comKe#tensionsKsam!$es5htm$Lconte#t/en's