1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-04 08:37:11 +02:00

dynamic url filtering

This commit is contained in:
gorhill 2015-05-21 14:15:17 -04:00
parent 6c3217d9af
commit 284b4f62d1
17 changed files with 1313 additions and 239 deletions

View File

@ -9,7 +9,7 @@
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="732"
height="1540.3398"
height="1740.3398"
id="svg2">
<defs
id="defs4">
@ -517,6 +517,66 @@
id="path11883"
style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1pt" />
</marker>
<marker
refX="0"
refY="0"
orient="auto"
id="TriangleOutMW-2"
style="overflow:visible">
<path
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
transform="scale(0.4,0.4)"
id="path9001-1"
style="fill:#00aa00;fill-rule:evenodd;stroke:#00aa00;stroke-width:1pt" />
</marker>
<marker
refX="0"
refY="0"
orient="auto"
id="DotMc-3"
style="overflow:visible">
<path
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
transform="matrix(0.4,0,0,0.4,2.96,0.4)"
id="path10345-9"
style="fill:#cc0000;fill-rule:evenodd;stroke:#cc0000;stroke-width:1pt" />
</marker>
<marker
refX="0"
refY="0"
orient="auto"
id="TriangleOutM-03"
style="overflow:visible">
<path
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
transform="scale(0.4,0.4)"
id="path4034-0"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" />
</marker>
<marker
refX="0"
refY="0"
orient="auto"
id="DiamondSPd-4"
style="overflow:visible">
<path
d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 z"
transform="scale(0.2,0.2)"
id="path11517-1"
style="fill:#b0b0b0;fill-rule:evenodd;stroke:#b0b0b0;stroke-width:1pt" />
</marker>
<marker
refX="0"
refY="0"
orient="auto"
id="TriangleOutM-9"
style="overflow:visible">
<path
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
transform="scale(0.4,0.4)"
id="path4034-2"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" />
</marker>
</defs>
<metadata
id="metadata7">
@ -603,15 +663,15 @@
rx="0.5"
ry="0.49999997"
x="240"
y="-97.637817"
y="102.36218"
id="rect3783-4"
style="fill:#ffeeaa;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<path
d="m 280,-857.63782 -180,0 0,1200"
d="m 280,-857.63782 -180,0 0,1399.99999"
id="path4799"
style="fill:none;stroke:#b0b0b0;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 710,-507.63782 c 0,346.66667 0,623.33333 0,970 l -280,0"
d="m 710,-507.63782 c 0,346.66667 0,823.33332 0,1169.99999 l -280,0"
id="path4987"
style="fill:none;stroke:#00aa00;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotM7);marker-end:url(#TriangleOutM-2n)" />
<text
@ -628,28 +688,28 @@
id="tspan7956">whitelisted?</tspan></text>
<text
x="390"
y="-47.637821"
y="152.36218"
id="text5171-7"
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="390"
y="-47.637821"
y="152.36218"
id="tspan5384">local dynamic</tspan><tspan
x="390"
y="-17.637821"
y="182.36218"
id="tspan5388">filtering rule?</tspan></text>
<path
d="m 519.99999,-57.637827 180,0"
d="m 519.99999,142.36217 180,0"
id="path5390"
style="opacity:0.95999995;fill:none;stroke:#00aa00;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutMW)" />
<text
x="550"
y="-67.637817"
y="132.36218"
id="text5574"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="550"
y="-67.637817"
y="132.36218"
id="tspan5576">allow</tspan></text>
<path
d="m 420,-607.63782 0,100"
@ -665,26 +725,26 @@
y="-357.86438"
id="tspan5948">no</tspan></text>
<text
x="550"
y="2.36218"
x="548.48438"
y="201.3231"
id="text5946-2"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="550"
y="2.36218"
x="548.48438"
y="201.3231"
id="tspan5948-1">noop</tspan></text>
<path
d="m 610,-507.63782 c 0,173.33333 0,596.66667 0,770 l -180,0"
d="m 610,-507.63782 c 0,173.33333 0,796.66666 0,969.99999 l -180,0"
id="path5390-8"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotM);marker-end:url(#TriangleOutM)" />
<text
x="440"
y="42.362179"
y="242.36218"
id="text5946-8"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="440"
y="42.362179"
y="242.36218"
id="tspan5948-6">no</tspan></text>
<rect
width="280"
@ -692,59 +752,59 @@
rx="0.5"
ry="0.49999997"
x="240"
y="102.36218"
y="302.36218"
id="rect3783-4-3"
style="fill:#ffeeaa;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<path
d="M 419.99999,22.362173 420,92.36218"
d="M 419.99999,222.36217 420,292.36218"
id="path5762-6"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#TriangleOutM)" />
<text
x="390"
y="152.36217"
y="352.36218"
id="text5171-7-9"
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="390"
y="152.36217"
y="352.36218"
id="tspan5384-4">global dynamic</tspan><tspan
x="390"
y="182.36217"
y="382.36218"
id="tspan5388-3">filtering rule?</tspan></text>
<path
d="m 519.89843,142.13559 180.10156,0.22658"
d="m 519.89843,342.13559 180.10156,0.22658"
id="path5390-1"
style="fill:none;stroke:#00aa00;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM9)" />
<text
x="550"
y="132.36218"
y="332.36218"
id="text5574-8"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="550"
y="132.36218"
y="332.36218"
id="tspan5576-4">allow</tspan></text>
<text
x="550"
y="202.36218"
x="548.48438"
y="401.32312"
id="text5946-2-9"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="550"
y="202.36218"
x="548.48438"
y="401.32312"
id="tspan5948-1-9">noop</tspan></text>
<path
d="M 519.99999,182.36216 600,182.36218"
d="M 519.99999,382.36216 600,382.36218"
id="path5390-8-2"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM-6)" />
<text
x="440"
y="242.36218"
y="442.36218"
id="text5946-8-3"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="440"
y="242.36218"
y="442.36218"
id="tspan6526">no</tspan></text>
<rect
width="280"
@ -752,24 +812,24 @@
rx="0.5"
ry="0.49999997"
x="240"
y="302.36218"
y="502.36218"
id="rect3783-4-31"
style="fill:#ffeeaa;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<path
d="M 419.99999,222.36216 420,292.36218"
d="M 419.99999,422.36216 420,492.36218"
id="path5762-6-3"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM)" />
<text
x="380"
y="362.36218"
y="562.36218"
id="text5171-7-1"
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="380"
y="362.36218"
y="562.36218"
id="tspan5388-5">static filtering?</tspan></text>
<path
d="m 99.999995,-57.637827 139.999995,0"
d="m 99.999995,142.36217 139.999995,0"
id="path8567"
style="fill:none;stroke:#b0b0b0;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#DiamondSPd)" />
<path
@ -783,59 +843,54 @@
rx="0.5"
ry="0.49999997"
x="240"
y="-297.63782"
y="-97.637817"
id="rect3783-7"
style="fill:#ffeeaa;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<path
d="m 420,-377.63782 0,70"
id="path5762"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM)" />
<text
x="380"
y="-247.63782"
y="-47.637817"
id="text5171-8"
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="380"
y="-247.63782"
y="-47.637817"
id="tspan5175-2"
style="font-style:italic;-inkscape-font-specification:Sans Italic">advanced user</tspan><tspan
x="380"
y="-217.63782"
y="-17.637817"
id="tspan5410">mode?</tspan></text>
<text
x="440"
y="-157.63782"
y="42.362183"
id="text5946-9"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="440"
y="-157.63782"
y="42.362183"
id="tspan5948-62">yes</tspan></text>
<path
d="m 420,-177.63782 0,70"
d="m 420,22.36218 0,70"
id="path5762-0"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM)" />
<path
d="m 520,-17.63782 80,0"
d="m 520,182.36218 80,0"
id="path5390-5"
style="opacity:0.95999995;fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM)" />
<text
x="540"
y="-197.63782"
x="538.51562"
y="1.3231113"
id="text5946-7"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="540"
y="-197.63782"
x="538.51562"
y="1.3231113"
id="tspan5948-9">no</tspan></text>
<path
d="m 520,730 80,0"
transform="translate(0,-947.63782)"
d="m 520,-17.63782 80,0"
id="path5695"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM-6)" />
<path
d="m 100,342.36218 140,0"
d="m 100,542.36218 140,0"
id="path8567-7"
style="fill:none;stroke:#b0b0b0;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#DiamondSOI)" />
<path
@ -844,17 +899,17 @@
id="path6779"
style="fill:none;stroke:#00aa00;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM-6b)" />
<path
d="m 420,422.36218 0,150"
d="m 420,622.36218 0,150"
id="path5762-6-3-1"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutMe9)" />
<text
x="460"
y="442.36218"
y="642.36218"
id="text5946-8-3-5"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><tspan
x="460"
y="442.36218"
y="642.36218"
id="tspan6526-8">no filter</tspan></text>
<text
x="180"
@ -887,65 +942,65 @@
y="-847.63782"
id="tspan5175-3-2">URL of page</tspan></text>
<path
d="m 340,22.36218 0,40"
d="m 340,222.36218 0,40"
id="path5762-6-9"
style="fill:none;stroke:#cc0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#DotMc);display:inline" />
<text
x="310"
y="42.362179"
y="242.36218"
id="text5946-8-7"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="310"
y="42.362179"
y="242.36218"
id="tspan5948-6-0">block</tspan></text>
<path
d="m 340,222.36218 0,40"
d="m 340,422.36218 0,40"
id="path5762-6-9-0"
style="fill:none;stroke:#cc0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#DotMA);display:inline" />
<text
x="310"
y="242.36218"
y="442.36218"
id="text5946-8-7-3"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="310"
y="242.36218"
y="442.36218"
id="tspan5948-6-0-3">block</tspan></text>
<path
d="m 520,342.36218 180,0"
d="m 520,542.36218 180,0"
id="path5390-1-2"
style="fill:none;stroke:#00aa00;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutMx);display:inline" />
<text
x="590"
y="332.36218"
y="532.36218"
id="text5946-2-9-9"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="590"
y="332.36218"
y="532.36218"
id="tspan5948-1-9-5">exception filter</tspan></text>
<path
d="m 340,422.36218 0,40"
d="m 340,622.36218 0,40"
id="path5762-6-9-0-9"
style="fill:none;stroke:#cc0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#DotMf);display:inline" />
<text
x="290"
y="442.36218"
y="642.36218"
id="text5946-8-7-3-2"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="290"
y="442.36218"
y="642.36218"
id="tspan5948-6-0-3-0">block filter</tspan></text>
<text
x="420"
y="602.36218"
y="802.36218"
id="text5946-8-7-3-2-4"
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="420"
y="602.36218"
y="802.36218"
id="tspan5948-6-0-3-0-2">remote server</tspan></text>
<text
x="540"
@ -957,8 +1012,7 @@
y="-467.63782"
id="tspan5948-62-1">yes</tspan></text>
<path
d="m 750,1450 -690,0"
transform="translate(0,-947.63782)"
d="m 750,702.36218 -690,0"
id="path12147"
style="fill:#cccccc;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:8, 8;stroke-dashoffset:0" />
<path
@ -966,13 +1020,91 @@
id="path12147-5"
style="fill:#cccccc;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:8, 8;stroke-dashoffset:0;display:inline" />
<text
x="638.15234"
y="-869.40344"
x="620"
y="-867.63782"
id="text5171-77-67"
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="638.15234"
y="-869.40344"
x="620"
y="-867.63782"
id="tspan5175-3-1">your browser</tspan></text>
<rect
width="280"
height="120"
rx="0.5"
ry="0.49999997"
x="240"
y="-297.63782"
id="rect3783-7-4"
style="fill:#ffeeaa;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
<path
d="m 420,-377.63782 0,70"
id="path5762"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM)" />
<text
x="380"
y="-247.63783"
id="text5171-8-9"
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="380"
y="-247.63783"
id="tspan5410-4">url filtering rule?</tspan></text>
<path
d="m 520,-257.63783 180,0"
id="path5390-2"
style="opacity:0.95999995;fill:none;stroke:#00aa00;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutMW);display:inline" />
<text
x="550"
y="-267.63782"
id="text5574-7"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="550"
y="-267.63782"
id="tspan5576-8">allow</tspan></text>
<path
d="m 340,-177.63783 0,40"
id="path5762-6-9-9"
style="fill:none;stroke:#cc0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#DotMc);display:inline" />
<text
x="310"
y="-157.63783"
id="text5946-8-7-7"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="310"
y="-157.63783"
id="tspan5948-6-0-4">block</tspan></text>
<text
x="440.89844"
y="-157.8644"
id="text5946-5"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="440.89844"
y="-157.8644"
id="tspan5948-8">no</tspan></text>
<path
d="m 420,-177.63783 0,70"
id="path5762-3"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM);display:inline" />
<path
d="m 100,-257.63782 140,0"
id="path8567-2"
style="fill:none;stroke:#b0b0b0;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#DiamondSPd);display:inline" />
<text
x="548.48438"
y="-198.6769"
id="text5946-2-8"
xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><tspan
x="548.48438"
y="-198.6769"
id="tspan5948-1-5">noop</tspan></text>
<path
d="m 520,-217.63783 80,0"
id="path5390-5-3"
style="opacity:0.95999995;fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM);display:inline" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "uBlock Origin",
"version": "0.9.7.5",
"version": "0.9.7.6",
"default_locale": "en",
"description": "__MSG_extShortDesc__",

View File

@ -17,6 +17,7 @@
<script src="js/assets.js"></script>
<script src="js/dynamic-net-filtering.js"></script>
<script src="js/static-net-filtering.js"></script>
<script src="js/url-net-filtering.js"></script>
<script src="js/cosmetic-filtering.js"></script>
<script src="js/hnswitches.js"></script>
<script src="js/ublock.js"></script>
@ -28,7 +29,6 @@
<script src="js/tab.js"></script>
<script src="js/traffic.js"></script>
<script src="js/contextmenu.js"></script>
<script src="js/mirrors.js"></script>
<script src="js/start.js"></script>
</body>
</html>

View File

@ -106,25 +106,25 @@ body.f table tr.f {
display: none;
}
#content table tr.cat_info {
#content tr.cat_info {
color: #00f;
}
#content table tr.blocked {
#content tr.blocked {
background-color: rgba(192, 0, 0, 0.1);
}
body.colorBlind #content table tr.blocked {
body.colorBlind #content tr.blocked {
background-color: rgba(0, 19, 110, 0.1);
}
#content table tr.allowed {
#content tr.allowed {
background-color: rgba(0, 160, 0, 0.1);
}
body.colorBlind #content table tr.allowed {
body.colorBlind #content tr.allowed {
background-color: rgba(255, 194, 57, 0.1)
}
#content table tr.cosmetic {
#content tr.cb {
background-color: rgba(255, 255, 0, 0.1);
}
#content table tr.maindoc {
#content tr.maindoc {
background-color: #666;
color: white;
text-align: center;
@ -140,13 +140,13 @@ body #content td {
word-break: break-all;
word-wrap: break-word;
}
#content table tr td {
#content tr td {
border-top: 1px solid #ccc;
}
#content table tr td:first-of-type {
#content tr td:first-of-type {
border-left: none;
}
#content table tr td:last-of-type {
#content tr td:last-of-type {
border-right: none;
}
body.compactView #content td {
@ -155,56 +155,63 @@ body.compactView #content td {
white-space: nowrap;
}
#content table tr td:nth-of-type(1) {
#content tr td:nth-of-type(1) {
text-align: right;
white-space: nowrap;
}
#content table tr td:nth-of-type(2) {
#content tr td:nth-of-type(2) {
text-align: center;
white-space: nowrap;
}
#content table tr.tab_bts > td:nth-of-type(2):before {
#content tr.tab_bts > td:nth-of-type(2):before {
content: '\f070';
font: 1em FontAwesome;
}
#content table tr.tab:not(.canMtx) {
#content tr.tab:not(.canMtx) {
opacity: 0.3;
}
#content table tr.tab:not(.canMtx):hover {
#content tr.tab:not(.canMtx):hover {
opacity: 0.7;
}
#content table tr.tab:not(.canMtx) > td:nth-of-type(2):before {
#content tr.tab:not(.canMtx) > td:nth-of-type(2):before {
content: '\f00d';
font: 1em FontAwesome;
}
body:not(.popupOn) #content table tr.canMtx td:nth-of-type(2) {
body:not(.popupOn) #content tr.canMtx td:nth-of-type(2) {
cursor: zoom-in;
}
body:not(.popupOn) #content table tr.canMtx td:nth-of-type(2):hover {
body:not(.popupOn) #content tr.canMtx td:nth-of-type(2):hover {
background: #ccc;
}
#content table tr.cat_net td:nth-of-type(3),
#content table tr.cat_cosmetic td:nth-of-type(3) {
#content tr.cat_net td:nth-of-type(3),
#content tr.cat_cosmetic td:nth-of-type(3) {
font: 12px monospace;
text-align: center;
white-space: nowrap;
}
#content table tr.cat_net td:nth-of-type(6) > span > b {
#content tr.cat_net td:nth-of-type(3) {
cursor: pointer;
position: relative;
}
#content tr.cat_net td:nth-of-type(3):hover {
background: #ccc;
}
#content tr.cat_net td:nth-of-type(6) > span > b {
font-weight: bold;
}
#content table tr td:nth-of-type(6) b {
#content tr td:nth-of-type(6) b {
font-weight: normal;
}
#content table tr.blocked td:nth-of-type(6) b {
#content tr.blocked td:nth-of-type(6) b {
background-color: rgba(192, 0, 0, 0.2);
}
body.colorBlind #content table tr.blocked td:nth-of-type(6) b {
body.colorBlind #content tr.blocked td:nth-of-type(6) b {
background-color: rgba(0, 19, 110, 0.2);
}
#content table tr.allowed td:nth-of-type(6) b {
#content tr.allowed td:nth-of-type(6) b {
background-color: rgba(0, 160, 0, 0.2);
}
body.colorBlind #content table tr.allowed td:nth-of-type(6) b {
body.colorBlind #content tr.allowed td:nth-of-type(6) b {
background-color: rgba(255, 194, 57, 0.2);
}
@ -255,3 +262,150 @@ body[dir="rtl"] #popupContainer > div {
#popupContainer.hide > iframe {
display: none;
}
#urlFilteringMenu {
background-color: rgba(0, 0, 0, 0.5);
border: 0;
bottom: 0;
left: 0;
margin: 0;
position: fixed;
right: 0;
top: 0;
z-index: 100;
}
#urlFilteringMenu .dialog {
background-color: white;
border: 1px solid gray;
padding: 0.2em;
position: fixed;
}
#urlFilteringMenu .dialog > div:first-child {
padding: 0.2em 0.2em 0.4em 0.2em;
}
#urlFilteringMenu .dialog > div:first-child > * {
display: inline-block;
vertical-align: middle;
}
#urlFilteringMenu .save {
background-color: #ffe;
border: 1px solid #ddc;
border-radius: 4px;
color: #888;
cursor: pointer;
font-size: 1.8em;
margin-right: 0.1em;
padding: 0.1em 0.5em;
visibility: hidden;
}
body.dirty #urlFilteringMenu .save {
visibility: visible;
}
#urlFilteringMenu .save:hover {
color: black;
}
#urlFilteringMenu select {
font: inherit;
}
#urlFilteringMenu .entries {
font-size: 13px;
max-height: 12em;
max-width: 70vw;
overflow-y: auto;
}
#urlFilteringMenu .entries > div {
background-color: #e6e6e6;
border: 0;
line-height: 2em;
margin: 0;
margin-top: 1px;
overflow: hidden;
padding: 0;
white-space: nowrap;
width: 100%;
}
#urlFilteringMenu .entries > div:first-child {
margin-top: 0;
}
#urlFilteringMenu .entries > div:hover {
background-color: #f0f0f0;
}
#urlFilteringMenu .entries > div > .action {
background-color: transparent;
border: 0;
border-right: 1px solid white;
cursor: pointer;
display: inline-block;
height: 100%;
width: 3.8em;
}
#urlFilteringMenu .entries > div > .action.allow {
background-color: rgba(0, 160, 0, 0.3);
}
body.colorBlind #urlFilteringMenu .entries > div > .action.allow {
background-color: rgba(255, 194, 57, 0.4);
}
#urlFilteringMenu .entries > div > .action.noop {
background-color: rgba(108, 108, 108, 0.3);
}
body.colorBlind #urlFilteringMenu .entries > div > .action.noop {
background-color: rgba(96, 96, 96, 0.4);
}
#urlFilteringMenu .entries > div > .action.block {
background-color: rgba(192, 0, 0, 0.3);
}
body.colorBlind #urlFilteringMenu .entries > div > .action.block {
background-color: rgba(0, 19, 110, 0.4);
}
#urlFilteringMenu .entries > div > .action.allow.own {
background-color: rgba(0, 160, 0, 1);
}
body.colorBlind #urlFilteringMenu .entries > div > .action.allow.own {
background-color: rgba(255, 194, 57, 1);
}
#urlFilteringMenu .entries > div > .action.noop.own {
background-color: rgba(108, 108, 108, 1);
}
#urlFilteringMenu .entries > div > .action.block.own {
background-color: rgba(192, 0, 0, 1);
}
body.colorBlind #urlFilteringMenu .entries > div > .action.block.own {
background-color: rgba(0, 19, 110, 1);
}
#urlFilteringMenu .entries > div > .action > span {
background-color: transparent;
border: 0;
display: inline-block;
height: 100%;
opacity: 0.2;
visibility: hidden;
width: 33.33%;
}
#urlFilteringMenu .entries > div > .action > span:before {
content: '\00A0';
}
#urlFilteringMenu .entries > div > .action:not(.own):hover > span {
opacity: 0.2;
visibility: visible;
}
#urlFilteringMenu .entries > div > .action:not(.own):hover > span:hover {
opacity: 0.75;
}
#urlFilteringMenu .entries > div > .action > .allow {
background-color: rgb(0, 160, 0);
}
body.colorBlind #urlFilteringMenu .entries > div > .action > .allow {
background-color: rgb(255, 194, 57);
}
#urlFilteringMenu .entries > div > .action > .noop {
background-color: rgb(108, 108, 108);
}
#urlFilteringMenu .entries > div > .action > .block {
background-color: rgb(192, 0, 0);
}
body.colorBlind #urlFilteringMenu .entries > div > .action > .block {
background-color: rgb(0, 19, 110);
}
#urlFilteringMenu .entries > div > .url {
padding: 0 0.25em;
}

View File

@ -41,7 +41,9 @@ var renderRules = function(details) {
var rules, rule, i;
// Switches always displayed first -- just like in uMatrix
// Merge url rules and switches: they just look the same
rules = details.hnSwitches.split(/\n+/).sort();
for ( i = 0; i < rules.length; i++ ) {
rule = rules[i];
liLeft = liTemplate.clone().text(rule);
@ -120,7 +122,7 @@ function handleImportFilePicker() {
.replace(/\n/g, ' * noop\n');
}
var request = {
'what': 'setSessionFirewallRules',
'what': 'setSessionRules',
'rules': rulesFromHTML('#diff .right li') + '\n' + result
};
messager.send(request, renderRules);
@ -183,7 +185,7 @@ var rulesFromHTML = function(selector) {
var revertHandler = function() {
var request = {
'what': 'setSessionFirewallRules',
'what': 'setSessionRules',
'rules': rulesFromHTML('#diff .left li')
};
messager.send(request, renderRules);
@ -193,7 +195,7 @@ var revertHandler = function() {
var commitHandler = function() {
var request = {
'what': 'setPermanentFirewallRules',
'what': 'setPermanentRules',
'rules': rulesFromHTML('#diff .right li')
};
messager.send(request, renderRules);
@ -217,7 +219,7 @@ var editStopHandler = function() {
var parent = uDom(this).ancestors('#diff');
parent.toggleClass('edit', false);
var request = {
'what': 'setSessionFirewallRules',
'what': 'setSessionRules',
'rules': uDom('#diff .right textarea').val()
};
messager.send(request, renderRules);
@ -245,7 +247,7 @@ uDom.onLoad(function() {
uDom('#editStopButton').on('click', editStopHandler);
uDom('#editCancelButton').on('click', editCancelHandler);
messager.send({ what: 'getFirewallRules' }, renderRules);
messager.send({ what: 'getRules' }, renderRules);
});
/******************************************************************************/

View File

@ -440,19 +440,21 @@ Matrix.prototype.mustAbort = function() {
/******************************************************************************/
Matrix.prototype.toFilterString = function() {
if ( this.r === 0 ) {
return '';
}
if ( this.type === '' ) {
return '';
}
var body = this.z + ' ' + this.y + ' ' + this.type;
if ( this.r === 1 ) {
return 'db:' + this.z + ' ' + this.y + ' ' + this.type + ' block';
return 'db:' + body + ' block';
}
if ( this.r === 2 ) {
return 'da:' + this.z + ' ' + this.y + ' ' + this.type + ' allow';
return 'da:' + body + ' allow';
}
if ( this.r === 3 ) {
return 'dn:' + this.z + ' ' + this.y + ' ' + this.type + ' noop';
}
return '';
/* this.r === 3 */
return 'dn:' + body + ' noop';
};
/******************************************************************************/
@ -529,6 +531,11 @@ Matrix.prototype.fromString = function(text, append) {
continue;
}
// URL net filtering rules
if ( line.indexOf('://') !== -1 ) {
continue;
}
// Valid rule syntax:
// srcHostname desHostname type state
@ -542,6 +549,12 @@ Matrix.prototype.fromString = function(text, append) {
continue;
}
// Ignore special rules:
// hostname-based switch rules
if ( fields[0].slice(-1) === ':' ) {
continue;
}
srcHostname = punycode.toASCII(fields[0]);
desHostname = punycode.toASCII(fields[1]);

View File

@ -50,6 +50,7 @@ var noTabId = '';
var allTabIds = {};
var allTabIdsToken;
var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
var reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
var prettyRequestTypes = {
'main_frame': 'doc',
@ -58,6 +59,13 @@ var prettyRequestTypes = {
'xmlhttprequest': 'xhr'
};
var uglyRequestTypes = {
'doc': 'main_frame',
'css': 'stylesheet',
'frame': 'sub_frame',
'xhr': 'xmlhttprequest'
};
var timeOptions = {
hour: '2-digit',
minute: '2-digit',
@ -84,40 +92,65 @@ var classNameFromTabId = function(tabId) {
/******************************************************************************/
var retextFromStaticFilteringResult = function(result) {
var retext = result.slice(3);
var pos = retext.indexOf('$');
if ( pos > 0 ) {
retext = retext.slice(0, pos);
}
if ( retext === '*' ) {
return '^.*$';
}
if ( retext.charAt(0) === '/' && retext.slice(-1) === '/' ) {
return retext.slice(1, -1);
}
return retext
.replace(/\./g, '\\.')
.replace(/\?/g, '\\?')
.replace('||', '')
.replace(/\^/g, '.')
.replace(/^\|/g, '^')
.replace(/\|$/g, '$')
.replace(/\*/g, '.*')
;
};
/******************************************************************************/
var retextFromURLFilteringResult = function(result) {
var beg = result.indexOf(' ');
var end = result.indexOf(' ', beg + 1);
var url = result.slice(beg + 1, end);
if ( url === '*' ) {
return '^.*$';
}
return '^' + url.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
};
/******************************************************************************/
// Emphasize hostname in URL, as this is what matters in uMatrix's rules.
var nodeFromURL = function(url, filter) {
if ( filter.charAt(0) !== 's' ) {
var filterType = filter.charAt(0);
if ( filterType !== 's' && filterType !== 'l' ) {
return document.createTextNode(url);
}
// make a regex out of the filter
var reText = filter.slice(3);
var pos = reText.indexOf('$');
if ( pos > 0 ) {
reText = reText.slice(0, pos);
var retext = '';
if ( filterType === 's' ) {
retext = retextFromStaticFilteringResult(filter);
} else if ( filterType === 'l' ) {
retext = retextFromURLFilteringResult(filter);
}
if ( reText === '*' ) {
reText = '\\*';
} else if ( reText.charAt(0) === '/' && reText.slice(-1) === '/' ) {
reText = reText.slice(1, -1);
} else {
reText = reText
.replace(/\./g, '\\.')
.replace(/\?/g, '\\?')
.replace('||', '')
.replace(/\^/g, '.')
.replace(/^\|/g, '^')
.replace(/\|$/g, '$')
.replace(/\*/g, '.*')
;
if ( retext === '' ) {
return document.createTextNode(url);
}
var re = new RegExp(reText, 'gi');
var re = new RegExp(retext, 'gi');
var matches = re.exec(url);
if ( matches === null || matches[0].length === 0 ) {
return document.createTextNode(url);
}
var node = renderedURLTemplate.cloneNode(true);
node.childNodes[0].textContent = url.slice(0, matches.index);
node.childNodes[1].textContent = url.slice(matches.index, re.lastIndex);
@ -153,6 +186,7 @@ var createRow = function(layout) {
var tr = trJunkyard.pop();
if ( tr ) {
tr.className = '';
tr.removeAttribute('data-context');
} else {
tr = document.createElement('tr');
}
@ -212,6 +246,7 @@ var renderNetLogEntry = function(tr, entry) {
var filter = entry.d0;
var type = entry.d1;
var url = entry.d2;
var td;
tr.classList.add('canMtx');
@ -221,19 +256,26 @@ var renderNetLogEntry = function(tr, entry) {
createGap(entry.tab, url);
}
// Cosmetic filter?
if ( filter.charAt(0) === 'c' ) {
tr.classList.add('cosmetic');
// Root hostname
if ( entry.d3 ) {
tr.setAttribute('data-context', entry.d3);
}
// Cosmetic filter?
var filterCat = filter.slice(0, 3);
if ( filterCat.charAt(2) === ':' ) {
tr.classList.add(filterCat.slice(0, 2));
}
td = tr.cells[2];
if ( filter.charAt(1) === 'b' ) {
tr.classList.add('blocked');
tr.cells[2].textContent = ' --';
td.textContent = '--';
} else if ( filter.charAt(1) === 'a' ) {
tr.classList.add('allowed');
tr.cells[2].textContent = ' ++';
td.textContent = '++';
} else {
tr.cells[2].textContent = '';
td.textContent = '';
}
var filterText = filter.slice(3);
@ -241,8 +283,8 @@ var renderNetLogEntry = function(tr, entry) {
filterText = '@@' + filterText;
}
tr.cells[3].textContent = filterText + '\t';
tr.cells[4].textContent = (prettyRequestTypes[type] || type) + '\t';
tr.cells[3].textContent = filterText;
tr.cells[4].textContent = (prettyRequestTypes[type] || type);
tr.cells[5].appendChild(nodeFromURL(url, filter));
};
@ -530,6 +572,236 @@ var onMaxEntriesChanged = function() {
truncateLog(maxEntries);
};
/******************************************************************************/
/******************************************************************************/
var urlFilteringMenu = (function() {
var menu = document.querySelector('#urlFilteringMenu');
var menuDialog = menu.querySelector('.dialog');
var selectContext = menuDialog.querySelector('.context');
var selectType = menuDialog.querySelector('.type');
var menuEntries = menu.querySelector('.entries');
var menuURLs = [];
var removeAllChildren = function(node) {
while ( node.firstChild ) {
node.removeChild(node.firstChild);
}
};
var uglyTypeFromSelector = function() {
var prettyType = selectType.value;
return uglyRequestTypes[prettyType] || prettyType;
};
var onColorsReady = function(response) {
document.body.classList.toggle('dirty', response.dirty);
var colorEntries = response.colors;
var colorEntry, node;
for ( var url in colorEntries ) {
if ( colorEntries.hasOwnProperty(url) === false ) {
continue;
}
colorEntry = colorEntries[url];
node = menu.querySelector('.entries [data-url="' + url + '"]');
if ( node === null ) {
continue;
}
node.classList.toggle('allow', colorEntry.r === 2);
node.classList.toggle('noop', colorEntry.r === 3);
node.classList.toggle('block', colorEntry.r === 1);
node.classList.toggle('own', colorEntry.own);
}
};
var colorize = function() {
messager.send({
what: 'getURLFilteringData',
context: selectContext.value,
urls: menuURLs,
type: uglyTypeFromSelector()
}, onColorsReady);
};
var onClick = function(ev) {
var target = ev.target;
// click outside the url filtering menu
if ( target.id === 'urlFilteringMenu' ) {
toggleOff();
return;
}
ev.stopPropagation();
// Save url filtering rule(s)
if ( target.classList.contains('save') ) {
messager.send({
what: 'saveURLFilteringRules',
context: selectContext.value,
urls: menuURLs,
type: uglyTypeFromSelector()
}, colorize);
return;
}
// Remove url filtering rule
if ( target.classList.contains('action') ) {
messager.send({
what: 'setURLFilteringRule',
context: selectContext.value,
url: target.getAttribute('data-url'),
type: uglyTypeFromSelector(),
action: 0
}, colorize);
return;
}
// add "allow" url filtering rule
if ( target.classList.contains('allow') ) {
messager.send({
what: 'setURLFilteringRule',
context: selectContext.value,
url: target.parentNode.getAttribute('data-url'),
type: uglyTypeFromSelector(),
action: 2
}, colorize);
return;
}
// add "block" url filtering rule
if ( target.classList.contains('noop') ) {
messager.send({
what: 'setURLFilteringRule',
context: selectContext.value,
url: target.parentNode.getAttribute('data-url'),
type: uglyTypeFromSelector(),
action: 3
}, colorize);
return;
}
// add "block" url filtering rule
if ( target.classList.contains('block') ) {
messager.send({
what: 'setURLFilteringRule',
context: selectContext.value,
url: target.parentNode.getAttribute('data-url'),
type: uglyTypeFromSelector(),
action: 1
}, colorize);
return;
}
};
var toggleOn = function(ev) {
var td = ev.target;
var tr = td.parentElement;
var cells = tr.cells;
var context = tr.getAttribute('data-context');
if ( !context ) {
return;
}
var type = cells[4].textContent.trim();
if ( !type ) {
return;
}
var pos, option;
// Fill context selector
removeAllChildren(selectContext);
for (;;) {
option = document.createElement('option');
option.textContent = context;
option.setAttribute('value', context);
pos = context.indexOf('.');
selectContext.appendChild(option);
if ( pos === -1 ) {
break;
}
context = context.slice(pos + 1);
}
option = document.createElement('option');
option.textContent = '*';
option.setAttribute('value', '*');
selectContext.appendChild(option);
// Fill type selector
selectType.options[0].textContent = type;
selectType.options[0].setAttribute('value', type);
selectType.selectedIndex = 0;
// Extract data needed to build URL filtering menu
var candidateURL = cells[5].textContent;
var matches = reRFC3986.exec(candidateURL);
if ( matches === null || !matches[1] || !matches[2] ) {
return;
}
// Shortest URL which for a valid URL filtering rule
var candidateRootURL = matches[1] + matches[2];
menuURLs.push(candidateRootURL);
var candidatePath = matches[3] || '';
pos = candidatePath.charAt(0) === '/' ? 1 : 0;
while ( pos < candidatePath.length ) {
pos = candidatePath.indexOf('/', pos + 1);
if ( pos === -1 ) {
pos = candidatePath.length;
}
menuURLs.push(candidateRootURL + candidatePath.slice(0, pos));
}
var candidateQuery = matches[4] || '';
if ( candidateQuery !== '') {
menuURLs.push(candidateRootURL + candidatePath + candidateQuery);
}
// Fill menu
var menuEntryTemplate = document.querySelector('#templates .urlFilteringMenuEntry');
// Adding URL filtering rules
var i = menuURLs.length;
var url, menuEntry;
while ( i-- ) {
url = menuURLs[i];
menuEntry = menuEntryTemplate.cloneNode(true);
menuEntry.children[0].setAttribute('data-url', url);
menuEntry.children[1].textContent = url;
menuEntries.appendChild(menuEntry);
}
colorize();
var rect = td.getBoundingClientRect();
menuDialog.style.setProperty('left', rect.left + 'px');
menuDialog.style.setProperty('top', rect.bottom + 'px');
document.body.appendChild(menu);
menu.addEventListener('click', onClick, true);
selectContext.addEventListener('change', colorize);
selectType.addEventListener('change', colorize);
};
var toggleOff = function() {
if ( menu.parentNode === null ) {
return;
}
removeAllChildren(menuEntries);
selectContext.removeEventListener('change', colorize);
selectType.removeEventListener('change', colorize);
menu.removeEventListener('click', onClick, true);
menu.parentNode.removeChild(menu);
menuURLs = [];
};
return {
toggleOn: toggleOn
};
})();
/******************************************************************************/
/******************************************************************************/
var rowFilterer = (function() {
@ -823,6 +1095,7 @@ uDom.onLoad(function() {
uDom('#clear').on('click', clearBuffer);
uDom('#maxEntries').on('change', onMaxEntriesChanged);
uDom('#content table').on('click', 'tr.canMtx > td:nth-of-type(2)', popupManager.toggleOn);
uDom('#content').on('click', 'tr.cat_net > td:nth-of-type(3)', urlFilteringMenu.toggleOn);
});
/******************************************************************************/

View File

@ -161,6 +161,7 @@ var janitor = function() {
logBuffer !== null &&
logBuffer.lastReadTime < (Date.now() - logBufferObsoleteAfter)
) {
api.writeOne = writeOneNoop;
logBuffer = logBuffer.dispose();
}
if ( logBuffer !== null ) {
@ -170,16 +171,18 @@ var janitor = function() {
/******************************************************************************/
var writeOneNoop = function() {
};
var writeOne = function() {
if ( logBuffer !== null ) {
logBuffer.writeOne(arguments);
}
logBuffer.writeOne(arguments);
};
/******************************************************************************/
var readAll = function() {
if ( logBuffer === null ) {
api.writeOne = writeOne;
logBuffer = new LogBuffer();
vAPI.setTimeout(janitor, logBufferObsoleteAfter);
}
@ -188,18 +191,20 @@ var readAll = function() {
/******************************************************************************/
var isObserved = function() {
var isEnabled = function() {
return logBuffer !== null;
};
/******************************************************************************/
return {
writeOne: writeOne,
var api = {
writeOne: writeOneNoop,
readAll: readAll,
isObserved: isObserved
isEnabled: isEnabled
};
return api;
/******************************************************************************/
/******************************************************************************/

View File

@ -183,30 +183,30 @@ var getHostnameDict = function(hostnameToCountMap) {
var getFirewallRules = function(srcHostname, desHostnames) {
var r = {};
var dFiltering = µb.sessionFirewall;
r['/ * *'] = dFiltering.evaluateCellZY('*', '*', '*').toFilterString();
r['/ * image'] = dFiltering.evaluateCellZY('*', '*', 'image').toFilterString();
r['/ * 3p'] = dFiltering.evaluateCellZY('*', '*', '3p').toFilterString();
r['/ * inline-script'] = dFiltering.evaluateCellZY('*', '*', 'inline-script').toFilterString();
r['/ * 1p-script'] = dFiltering.evaluateCellZY('*', '*', '1p-script').toFilterString();
r['/ * 3p-script'] = dFiltering.evaluateCellZY('*', '*', '3p-script').toFilterString();
r['/ * 3p-frame'] = dFiltering.evaluateCellZY('*', '*', '3p-frame').toFilterString();
var df = µb.sessionFirewall;
r['/ * *'] = df.evaluateCellZY('*', '*', '*').toFilterString();
r['/ * image'] = df.evaluateCellZY('*', '*', 'image').toFilterString();
r['/ * 3p'] = df.evaluateCellZY('*', '*', '3p').toFilterString();
r['/ * inline-script'] = df.evaluateCellZY('*', '*', 'inline-script').toFilterString();
r['/ * 1p-script'] = df.evaluateCellZY('*', '*', '1p-script').toFilterString();
r['/ * 3p-script'] = df.evaluateCellZY('*', '*', '3p-script').toFilterString();
r['/ * 3p-frame'] = df.evaluateCellZY('*', '*', '3p-frame').toFilterString();
if ( typeof srcHostname !== 'string' ) {
return r;
}
r['. * *'] = dFiltering.evaluateCellZY(srcHostname, '*', '*').toFilterString();
r['. * image'] = dFiltering.evaluateCellZY(srcHostname, '*', 'image').toFilterString();
r['. * 3p'] = dFiltering.evaluateCellZY(srcHostname, '*', '3p').toFilterString();
r['. * inline-script'] = dFiltering.evaluateCellZY(srcHostname, '*', 'inline-script').toFilterString();
r['. * 1p-script'] = dFiltering.evaluateCellZY(srcHostname, '*', '1p-script').toFilterString();
r['. * 3p-script'] = dFiltering.evaluateCellZY(srcHostname, '*', '3p-script').toFilterString();
r['. * 3p-frame'] = dFiltering.evaluateCellZY(srcHostname, '*', '3p-frame').toFilterString();
r['. * *'] = df.evaluateCellZY(srcHostname, '*', '*').toFilterString();
r['. * image'] = df.evaluateCellZY(srcHostname, '*', 'image').toFilterString();
r['. * 3p'] = df.evaluateCellZY(srcHostname, '*', '3p').toFilterString();
r['. * inline-script'] = df.evaluateCellZY(srcHostname, '*', 'inline-script').toFilterString();
r['. * 1p-script'] = df.evaluateCellZY(srcHostname, '*', '1p-script').toFilterString();
r['. * 3p-script'] = df.evaluateCellZY(srcHostname, '*', '3p-script').toFilterString();
r['. * 3p-frame'] = df.evaluateCellZY(srcHostname, '*', '3p-frame').toFilterString();
for ( var desHostname in desHostnames ) {
if ( desHostnames.hasOwnProperty(desHostname) ) {
r['/ ' + desHostname + ' *'] = dFiltering.evaluateCellZY('*', desHostname, '*').toFilterString();
r['. ' + desHostname + ' *'] = dFiltering.evaluateCellZY(srcHostname, desHostname, '*').toFilterString();
r['/ ' + desHostname + ' *'] = df.evaluateCellZY('*', desHostname, '*').toFilterString();
r['. ' + desHostname + ' *'] = df.evaluateCellZY(srcHostname, desHostname, '*').toFilterString();
}
}
return r;
@ -853,18 +853,19 @@ var µb = µBlock;
var getRules = function() {
return {
permanentRules: µb.permanentFirewall.toString(),
sessionRules: µb.sessionFirewall.toString(),
permanentRules: µb.permanentFirewall.toString() + '\n' + µb.permanentURLFiltering.toString(),
sessionRules: µb.sessionFirewall.toString() + '\n' + µb.sessionURLFiltering.toString(),
hnSwitches: µb.hnSwitches.toString()
};
};
// Untangle rules and switches.
// Untangle firewall rules, url rules and switches.
var untangle = function(s) {
var textEnd = s.length;
var lineBeg = 0, lineEnd;
var line;
var rules = [];
var firewallRules = [];
var urlRules = [];
var switches = [];
while ( lineBeg < textEnd ) {
@ -878,16 +879,18 @@ var untangle = function(s) {
line = s.slice(lineBeg, lineEnd).trim();
lineBeg = lineEnd + 1;
// Switches always contain a ':'
if ( line.indexOf(':') === -1 ) {
rules.push(line);
if ( line.indexOf('://') !== -1 ) {
urlRules.push(line);
} else if ( line.indexOf(':') === -1 ) {
firewallRules.push(line);
} else {
switches.push(line);
}
}
return {
rules: rules.join('\n'),
firewallRules: firewallRules.join('\n'),
urlRules: urlRules.join('\n'),
switches: switches.join('\n')
};
};
@ -906,24 +909,27 @@ var onMessage = function(request, sender, callback) {
var response;
switch ( request.what ) {
case 'getFirewallRules':
case 'getRules':
response = getRules();
break;
case 'setSessionFirewallRules':
case 'setSessionRules':
// https://github.com/chrisaljoudi/uBlock/issues/772
µb.cosmeticFilteringEngine.removeFromSelectorCache('*');
r = untangle(request.rules);
µb.sessionFirewall.fromString(r.rules);
µb.sessionFirewall.fromString(r.firewallRules);
µb.sessionURLFiltering.fromString(r.urlRules);
µb.hnSwitches.fromString(r.switches);
µb.saveHostnameSwitches();
response = getRules();
break;
case 'setPermanentFirewallRules':
case 'setPermanentRules':
r = untangle(request.rules);
µb.permanentFirewall.fromString(r.rules);
µb.permanentFirewall.fromString(r.firewallRules);
µb.savePermanentFirewallRules();
µb.permanentURLFiltering.fromString(r.urlRules);
µb.savePermanentURLFilteringRules();
µb.hnSwitches.fromString(r.switches);
µb.saveHostnameSwitches();
response = getRules();
@ -1031,6 +1037,7 @@ var backupUserData = function(callback) {
filterLists: {},
netWhitelist: µb.stringFromWhitelist(µb.netWhitelist),
dynamicFilteringString: µb.permanentFirewall.toString(),
urlFilteringString: µb.permanentURLFiltering.toString(),
hostnameSwitchesString: µb.hnSwitches.toString(),
userFilters: ''
};
@ -1067,7 +1074,7 @@ var backupUserData = function(callback) {
var restoreUserData = function(request) {
var userData = request.userData;
var countdown = 7;
var countdown = 8;
var onCountdown = function() {
countdown -= 1;
if ( countdown === 0 ) {
@ -1088,6 +1095,7 @@ var restoreUserData = function(request) {
var s = userData.dynamicFilteringString || userData.userSettings.dynamicFilteringString || '';
µb.keyvalSetOne('dynamicFilteringString', s, onCountdown);
µb.keyvalSetOne('urlFilteringString', userData.urlFilteringString || '', onCountdown);
µb.keyvalSetOne('hostnameSwitchesString', userData.hostnameSwitchesString || '', onCountdown);
µb.assets.put('assets/user/filters.txt', userData.userFilters, onCountdown);
vAPI.storage.set({
@ -1173,6 +1181,66 @@ var µb = µBlock;
/******************************************************************************/
var getURLFilteringData = function(details) {
var colors = {};
var response = {
dirty: false,
colors: colors
};
var suf = µb.sessionURLFiltering;
var puf = µb.permanentURLFiltering;
var urls = details.urls,
context = details.context,
type = details.type;
var url, colorEntry;
var i = urls.length;
while ( i-- ) {
url = urls[i];
colorEntry = colors[url] = { r: 0, own: false };
if ( suf.evaluateZ(context, url, type).r !== 0 ) {
colorEntry.r = suf.r;
colorEntry.own = suf.context === context && suf.url === url && suf.type === type;
}
if ( response.dirty ) {
continue;
}
puf.evaluateZ(context, url, type);
response.dirty = colorEntry.own !== (puf.context === context && puf.url === url && puf.type === type);
}
return response;
};
/******************************************************************************/
var saveTemporaryURLFilteringRules = function(details) {
var changed = false;
var suf = µb.sessionURLFiltering;
var puf = µb.permanentURLFiltering;
var urls = details.urls,
context = details.context,
type = details.type;
var url, sOwn, pOwn;
var i = urls.length;
while ( i-- ) {
url = urls[i];
suf.evaluateZ(context, url, type);
sOwn = suf.context === context && suf.url === url && suf.type === type;
puf.evaluateZ(context, url, type);
pOwn = puf.context === context && puf.url === url && puf.type === type;
if ( sOwn && !pOwn ) {
puf.setRule(context, url, type, suf.r);
changed = true;
}
if ( !sOwn && pOwn ) {
puf.removeRule(context, url, type);
changed = true;
}
}
return changed;
};
/******************************************************************************/
var onMessage = function(request, sender, callback) {
// Async
switch ( request.what ) {
@ -1207,6 +1275,20 @@ var onMessage = function(request, sender, callback) {
};
break;
case 'saveURLFilteringRules':
if ( saveTemporaryURLFilteringRules(request) ) {
µb.savePermanentURLFilteringRules();
}
break;
case 'setURLFilteringRule':
µb.toggleURLFilteringRule(request);
break;
case 'getURLFilteringData':
response = getURLFilteringData(request);
break;
default:
return vAPI.messaging.UNHANDLED;
}

View File

@ -1,7 +1,7 @@
/*******************************************************************************
µBlock - a browser extension to block requests.
Copyright (C) 2014 Raymond Hill
uBlock - a browser extension to block requests.
Copyright (C) 2014-2015 Raymond Hill
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -498,26 +498,21 @@ PageStore.prototype.filterRequest = function(context) {
return entry.result;
}
var result = '';
µb.sessionURLFiltering.evaluateZ(context.rootHostname, context.requestURL, context.requestType);
var result = µb.sessionURLFiltering.toFilterString();
// Given that:
// - Dynamic filtering override static filtering
// - Evaluating dynamic filtering is much faster than static filtering
// We evaluate dynamic filtering first, and hopefully we can skip
// evaluation of static filtering.
if ( µb.userSettings.advancedUserEnabled ) {
var df = µb.sessionFirewall.evaluateCellZY(
context.rootHostname,
context.requestHostname,
context.requestType
);
if ( df.mustBlockOrAllow() ) {
result = df.toFilterString();
}
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
µb.sessionFirewall.evaluateCellZY( context.rootHostname, context.requestHostname, context.requestType);
result = µb.sessionFirewall.toFilterString();
}
// Static filtering never override dynamic filtering
if ( result === '' ) {
if ( result === '' || result.charAt(1) === 'n' ) {
result = µb.staticNetFilteringEngine.matchString(context);
}
@ -541,26 +536,21 @@ PageStore.prototype.filterRequestNoCache = function(context) {
return '';
}
var result = '';
µb.sessionURLFiltering.evaluateZ(context.rootHostname, context.requestURL, context.requestType);
var result = µb.sessionURLFiltering.toFilterString();
// Given that:
// - Dynamic filtering override static filtering
// - Evaluating dynamic filtering is much faster than static filtering
// We evaluate dynamic filtering first, and hopefully we can skip
// evaluation of static filtering.
if ( µb.userSettings.advancedUserEnabled ) {
var df = µb.sessionFirewall.evaluateCellZY(
context.rootHostname,
context.requestHostname,
context.requestType
);
if ( df.mustBlockOrAllow() ) {
result = df.toFilterString();
}
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
µb.sessionFirewall.evaluateCellZY(context.rootHostname, context.requestHostname, context.requestType);
result = µb.sessionFirewall.toFilterString();
}
// Static filtering never override dynamic filtering
if ( result === '' ) {
if ( result === '' || result.charAt(1) === 'n' ) {
result = µb.staticNetFilteringEngine.matchString(context);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
µBlock - a browser extension to block requests.
uBlock - a browser extension to block requests.
Copyright (C) 2014-2015 Raymond Hill
This program is free software: you can redistribute it and/or modify
@ -142,11 +142,12 @@ var onUserSettingsReady = function(fetched) {
// https://github.com/chrisaljoudi/uBlock/issues/540
// Disabling local mirroring for the time being
userSettings.experimentalEnabled = false;
µb.mirrors.toggle(false /* userSettings.experimentalEnabled */);
µb.contextMenu.toggle(userSettings.contextMenuEnabled);
µb.permanentFirewall.fromString(fetched.dynamicFilteringString);
µb.sessionFirewall.assign(µb.permanentFirewall);
µb.permanentURLFiltering.fromString(fetched.urlFilteringString);
µb.sessionURLFiltering.assign(µb.permanentURLFiltering);
µb.hnSwitches.fromString(fetched.hostnameSwitchesString);
// Remove obsolete setting
@ -226,6 +227,7 @@ return function() {
var fetchableProps = {
'compiledMagic': '',
'dynamicFilteringString': '',
'urlFilteringString': '',
'hostnameSwitchesString': '',
'lastRestoreFile': '',
'lastRestoreTime': 0,

View File

@ -1,6 +1,6 @@
/*******************************************************************************
µBlock - a browser extension to block requests.
uBlock - a browser extension to block requests.
Copyright (C) 2014-2015 Raymond Hill
This program is free software: you can redistribute it and/or modify
@ -83,6 +83,12 @@
/******************************************************************************/
µBlock.savePermanentURLFilteringRules = function() {
this.keyvalSetOne('urlFilteringString', this.permanentURLFiltering.toString());
};
/******************************************************************************/
µBlock.saveHostnameSwitches = function() {
this.keyvalSetOne('hostnameSwitchesString', this.hnSwitches.toString());
};

View File

@ -482,7 +482,8 @@ vAPI.tabs.onPopup = function(details) {
'net',
result,
'popup',
targetURL
targetURL,
openerHostname
);
// Not blocked

View File

@ -92,7 +92,7 @@ var onBeforeRequest = function(details) {
// Possible outcomes: blocked, allowed-passthru, allowed-mirror
pageStore.logRequest(requestContext, result);
µb.logger.writeOne(tabId, 'net', result, requestType, requestURL);
µb.logger.writeOne(tabId, 'net', result, requestType, requestURL, requestContext.rootHostname);
// Not blocked
if ( µb.isAllowResult(result) ) {
@ -187,7 +187,7 @@ var onBeforeRootFrameRequest = function(details) {
if ( pageStore ) {
pageStore.logRequest(context, result);
}
µb.logger.writeOne(tabId, 'net', result, 'main_frame', requestURL);
µb.logger.writeOne(tabId, 'net', result, 'main_frame', requestURL, context.rootHostname);
// Not blocked
if ( µb.isAllowResult(result) ) {
@ -279,7 +279,7 @@ var onBeforeBehindTheSceneRequest = function(details) {
}
pageStore.logRequest(context, result);
µb.logger.writeOne(vAPI.noTabId, 'net', result, details.type, details.url);
µb.logger.writeOne(vAPI.noTabId, 'net', result, details.type, details.url, context.rootHostname);
// Not blocked
if ( µb.isAllowResult(result) ) {
@ -328,7 +328,7 @@ var onHeadersReceived = function(details) {
var result = pageStore.filterRequestNoCache(context);
pageStore.logRequest(context, result);
µb.logger.writeOne(tabId, 'net', result, 'inline-script', details.url);
µb.logger.writeOne(tabId, 'net', result, 'inline-script', details.url, context.rootHostname);
// Don't block
if ( µb.isAllowResult(result) ) {
@ -378,7 +378,7 @@ var onRootFrameHeadersReceived = function(details) {
var result = pageStore.filterRequestNoCache(context);
pageStore.logRequest(context, result);
µb.logger.writeOne(tabId, 'net', result, 'inline-script', details.url);
µb.logger.writeOne(tabId, 'net', result, 'inline-script', details.url, context.rootHostname);
// Don't block
if ( µb.isAllowResult(result) ) {

View File

@ -254,8 +254,8 @@ var matchWhitelistDirective = function(url, hostname, directive) {
// Pre-change
switch ( name ) {
default:
break;
default:
break;
}
// Change
@ -263,23 +263,18 @@ var matchWhitelistDirective = function(url, hostname, directive) {
// Post-change
switch ( name ) {
case 'collapseBlocked':
if ( value === false ) {
this.cosmeticFilteringEngine.removeFromSelectorCache('*', 'net');
}
break;
case 'contextMenuEnabled':
this.contextMenu.toggle(value);
break;
case 'experimentalEnabled':
if ( typeof this.mirrors === 'object' ) {
// https://github.com/chrisaljoudi/uBlock/issues/540
// Disabling local mirroring for the time being
this.mirrors.toggle(false /* value */);
}
break;
default:
break;
case 'collapseBlocked':
if ( value === false ) {
this.cosmeticFilteringEngine.removeFromSelectorCache('*', 'net');
}
break;
case 'contextMenuEnabled':
this.contextMenu.toggle(value);
break;
case 'experimentalEnabled':
break;
default:
break;
}
this.saveUserSettings();
@ -317,6 +312,23 @@ var matchWhitelistDirective = function(url, hostname, directive) {
/******************************************************************************/
µBlock.toggleURLFilteringRule = function(details) {
var changed = this.sessionURLFiltering.setRule(
details.context,
details.url,
details.type,
details.action
);
if ( !changed ) {
return;
}
this.cosmeticFilteringEngine.removeFromSelectorCache(details.context, 'net');
};
/******************************************************************************/
µBlock.isBlockResult = function(result) {
return typeof result === 'string' && result.charAt(1) === 'b';
};

391
src/js/url-net-filtering.js Normal file
View File

@ -0,0 +1,391 @@
/*******************************************************************************
uBlock - a browser extension to black/white list requests.
Copyright (C) 2015 Raymond Hill
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
/* global µBlock */
/******************************************************************************/
// The purpose of log filtering is to create ad hoc filtering rules, to
// diagnose and assist in the creation of custom filters.
µBlock.URLNetFiltering = (function() {
'use strict';
/*******************************************************************************
buckets: map of [origin + urlkey]
bucket: array of rule entry, sorted from shorter to longer url
rule entry: { url, action }
*******************************************************************************/
/******************************************************************************/
var actionToNameMap = {
1: 'block',
2: 'allow',
3: 'noop'
};
var nameToActionMap = {
'block': 1,
'allow': 2,
'noop': 3
};
/******************************************************************************/
var RuleEntry = function(url, action) {
this.url = url;
this.action = action;
};
/******************************************************************************/
var indexOfURL = function(urls, url) {
// TODO: binary search -- maybe, depends on common use cases
var urlLen = url.length;
var entry;
// urls must be ordered by increasing length.
for ( var i = 0; i< urls.length; i++ ) {
entry = urls[i];
if ( entry.url.length > urlLen ) {
break;
}
if ( entry.url === url ) {
return i;
}
}
return -1;
};
/******************************************************************************/
var indexOfMatch = function(urls, url) {
// TODO: binary search -- maybe, depends on common use cases
var urlLen = url.length;
var i = urls.length;
var entry;
while ( i-- ) {
entry = urls[i];
if ( entry.url.length > urlLen ) {
continue;
}
if ( url.lastIndexOf(entry.url, 0) === 0 ) {
return i;
}
}
return -1;
};
/******************************************************************************/
var indexFromLength = function(urls, len) {
// TODO: binary search -- maybe, depends on common use cases
// urls must be ordered by increasing length.
for ( var i = 0; i< urls.length; i++ ) {
if ( urls[i].url.length > len ) {
return i;
}
}
return -1;
};
/******************************************************************************/
var addRuleEntry = function(urls, url, action) {
var entry = new RuleEntry(url, action);
var i = indexFromLength(urls, url.length);
if ( i === -1 ) {
urls.push(entry);
} else {
urls.splice(i, 0, entry);
}
};
/******************************************************************************/
var urlKeyFromURL = function(url) {
var match = reURLKey.exec(url);
return match !== null ? match[0] : '';
};
var reURLKey = /^[a-z]+:\/\/[^\/?#]+/;
/******************************************************************************/
var URLNetFiltering = function() {
this.reset();
};
/******************************************************************************/
// rules:
// hostname + urlkey => urls
// urls = collection of urls to match
URLNetFiltering.prototype.reset = function() {
this.rules = Object.create(null);
// registers, filled with result of last evaluation
this.context = '';
this.url = '';
this.type = '';
this.r = 0;
};
/******************************************************************************/
URLNetFiltering.prototype.assign = function(other) {
var thisRules = this.rules;
var otherRules = other.rules;
var k;
// Remove rules not in other
for ( k in thisRules ) {
if ( otherRules[k] === undefined ) {
delete thisRules[k];
}
}
// Add/change rules in other
for ( k in otherRules ) {
thisRules[k] = otherRules[k].slice();
}
};
/******************************************************************************/
URLNetFiltering.prototype.setRule = function(srcHostname, url, type, action) {
if ( action === 0 ) {
return this.removeRule(srcHostname, url, type);
}
var urlKey = urlKeyFromURL(url);
if ( urlKey === '' ) {
return false;
}
var bucketKey = srcHostname + ' ' + urlKey + ' ' + type;
var urls = this.rules[bucketKey];
if ( urls === undefined ) {
urls = this.rules[bucketKey] = [];
}
var entry;
var i = indexOfURL(urls, url);
if ( i !== -1 ) {
entry = urls[i];
if ( entry.action === action ) {
return false;
}
entry.action = action;
return true;
}
addRuleEntry(urls, url, action);
return true;
};
/******************************************************************************/
URLNetFiltering.prototype.removeRule = function(srcHostname, url, type) {
var urlKey = urlKeyFromURL(url);
if ( urlKey === '' ) {
return false;
}
var bucketKey = srcHostname + ' ' + urlKey + ' ' + type;
var urls = this.rules[bucketKey];
if ( urls === undefined ) {
return false;
}
var i = indexOfURL(urls, url);
if ( i === -1 ) {
return false;
}
urls.splice(i, 1);
if ( urls.length === 0 ) {
delete this.rules[bucketKey];
}
return true;
};
/******************************************************************************/
URLNetFiltering.prototype.evaluateZ = function(context, target, type) {
var urlKey = urlKeyFromURL(target);
if ( urlKey === '' ) {
this.r = 0;
return this;
}
var urls, pos, i, entry, prefixKey;
for (;;) {
this.context = context;
prefixKey = context + ' ' + urlKey;
if ( urls = this.rules[prefixKey + ' ' + type] ) {
i = indexOfMatch(urls, target);
if ( i !== -1 ) {
entry = urls[i];
this.url = entry.url;
this.type = type;
this.r = entry.action;
return this;
}
}
if ( urls = this.rules[prefixKey + ' *'] ) {
i = indexOfMatch(urls, target);
if ( i !== -1 ) {
entry = urls[i];
this.url = entry.url;
this.type = '*';
this.r = entry.action;
return this;
}
}
if ( context === '*' ) {
break;
}
pos = context.indexOf('.');
context = pos !== -1 ? context.slice(pos + 1) : '*';
}
this.r = 0;
return this;
};
/******************************************************************************/
URLNetFiltering.prototype.mustBlockOrAllow = function() {
return this.r === 1 || this.r === 2;
};
/******************************************************************************/
URLNetFiltering.prototype.toFilterString = function() {
if ( this.r === 0 ) {
return '';
}
var body = this.context + ' ' + this.url + ' ' + this.type;
if ( this.r === 1 ) {
return 'lb:' + body + ' block';
}
if ( this.r === 2 ) {
return 'la:' + body + ' allow';
}
/* this.r === 3 */
return 'ln:' + body + ' noop';
};
/******************************************************************************/
// "url-filtering:" hostname url action
URLNetFiltering.prototype.toString = function() {
var out = [];
var pos, hn, type, urls, i, entry;
for ( var bucketKey in this.rules ) {
pos = bucketKey.indexOf(' ');
hn = bucketKey.slice(0, pos);
pos = bucketKey.lastIndexOf(' ');
type = bucketKey.slice(pos + 1);
urls = this.rules[bucketKey];
for ( i = 0; i < urls.length; i++ ) {
entry = urls[i];
out.push(
hn + ' ' +
entry.url + ' ' +
type + ' ' +
actionToNameMap[entry.action]
);
}
}
return out.sort().join('\n');
};
/******************************************************************************/
URLNetFiltering.prototype.fromString = function(text) {
var textEnd = text.length;
var lineBeg = 0, lineEnd;
var line, fields;
this.reset();
while ( lineBeg < textEnd ) {
lineEnd = text.indexOf('\n', lineBeg);
if ( lineEnd < 0 ) {
lineEnd = text.indexOf('\r', lineBeg);
if ( lineEnd < 0 ) {
lineEnd = textEnd;
}
}
line = text.slice(lineBeg, lineEnd).trim();
lineBeg = lineEnd + 1;
if ( line === '' ) {
continue;
}
// Coarse test
if ( line.indexOf('://') === -1 ) {
continue;
}
fields = line.split(/\s+/);
if ( fields.length !== 4 ) {
continue;
}
// Finer test
if ( fields[1].indexOf('://') === -1 ) {
continue;
}
if ( nameToActionMap.hasOwnProperty(fields[3]) === false ) {
continue;
}
this.setRule(fields[0], fields[1], fields[2], nameToActionMap[fields[3]]);
}
};
/******************************************************************************/
return URLNetFiltering;
/******************************************************************************/
})();
/******************************************************************************/
µBlock.sessionURLFiltering = new µBlock.URLNetFiltering();
µBlock.permanentURLFiltering = new µBlock.URLNetFiltering();
/******************************************************************************/

View File

@ -38,10 +38,21 @@
<div><span>&#xf068;</span>&ensp;<span>&#xf00d;</span></div>
</div>
<div style="display: none;">
<div id="templates" style="display: none;">
<div id="renderedURLTemplate"><span><span></span><b></b><span></span></span></div>
<div id="hiddenTemplate"><span style="display:none;"></span></div>
<div id="urlFilteringMenu">
<div class="dialog">
<div>
<span class="fa save">&#xf023;</span>
<label>Context: <select class="context"></select></label>&emsp;
<label>Type: <select class="type"><option><option value="*">*</select></label>
</div>
<div class="entries"></div>
</div>
</div>
<div class="urlFilteringMenuEntry"><span class="action"><span class="allow"></span><span class="noop"></span><span class="block"></span></span><span class="url"></span></div>
</div>
<script src="js/vapi-common.js"></script>
<script src="js/vapi-client.js"></script>