├── .gitignore ├── CONTRIBUTING.markdown ├── LICENSE ├── README.markdown ├── chrome.manifest ├── container ├── chrome │ ├── background.html │ ├── config.js │ ├── container.js │ ├── host_file_wrapper.js │ └── timer.js └── firefox │ ├── config.js │ ├── container.js │ ├── firstrun.js │ ├── host_file_wrapper.js │ ├── hostadmin.css │ ├── hostadmin.xul │ ├── refresh_dns.js │ ├── statusbar.js │ └── timer.js ├── core ├── editor.html ├── editor.js ├── glue.js ├── hostadmin.js ├── init.js ├── lib │ ├── CodeMirror │ │ ├── LICENSE │ │ ├── addon │ │ │ └── selection │ │ │ │ └── active-line.js │ │ ├── lib │ │ │ ├── codemirror.css │ │ │ └── codemirror.js │ │ └── mode │ │ │ └── hostadmin │ │ │ └── hostadmin.js │ ├── bootstrap │ │ ├── css │ │ │ └── bootstrap.min.css │ │ ├── img │ │ │ ├── glyphicons-halflings-white.png │ │ │ └── glyphicons-halflings.png │ │ └── js │ │ │ └── bootstrap.min.js │ ├── jquery-1.8.3.min.js │ └── levenshtein.js ├── popup.html └── popup.js ├── defaults └── preferences │ └── prefs.js ├── dist ├── dist-chrome.sh ├── dist-firefox.sh ├── icons ├── icon128.png ├── icon16.png ├── icon24.png └── icon32.png ├── install.rdf ├── manifest.json └── npapi ├── hostadmin.amd64.so ├── hostadmin.dll ├── hostadmin.plugin └── Contents │ ├── Info.plist │ └── MacOS │ └── hostadmin ├── hostadmin.x86.so └── src ├── Makefile ├── const.h ├── hostadmin-Info.plist ├── hostadmin.c ├── hostadmin.def ├── hostadmin.h ├── hostadmin.rc ├── hostadmin.sln ├── hostadmin.vcproj ├── hostadmin.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── npapi_headers ├── npapi.h ├── npfunctions.h ├── npruntime.h └── nptypes.h /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | 3 | npapi/src/hostadmin.vcproj.* 4 | npapi/src/hostadmin.ncb 5 | npapi/src/hostadmin.suo 6 | npapi/src/Release/ 7 | npapi/src/Debug/ 8 | 9 | npapi/src/*.so 10 | npapi/src/*.o 11 | 12 | xcuserdata 13 | 14 | .DS_Store 15 | *.swp 16 | *~.nib 17 | 18 | *.zip 19 | *.crx 20 | *.xpi 21 | -------------------------------------------------------------------------------- /CONTRIBUTING.markdown: -------------------------------------------------------------------------------- 1 | Contributing to HostAdmin 2 | ========================= 3 | Patchs are welcomed. Follow instructions below to make some change to HostAdmin 4 | 5 | Envirment 6 | --------- 7 | 8 | ### Getting sources 9 | 10 | 11 | git clone https://github.com/tg123/chrome-hostadmin.git 12 | 13 | 14 | 15 | ### Firefox 16 | 17 | 1. Create your dev profile. You can get detail from [Setting up an extension development environment](https://developer.mozilla.org/en/docs/Setting_up_extension_development_environment) 18 | 19 | 1. Link HostAdmin to Firefox dev profile (Linux) 20 | 21 | 22 | ln -s /path/to/chrome-hostadmin/ ~/.mozilla/firefox/YOURDEVPROFILENAME/extensions/\{bd54afa8-b14a-4d7a-aecf-37e34e882796\} 23 | 24 | 25 | 1. Start dev firefox with dev profile 26 | 27 | 28 | firefox -P dev 29 | 30 | 31 | 32 | ### Chrome 33 | 34 | 1. Open [chrome://extensions/](chrome://extensions/) 35 | 1. Enable `Developer mode` and use `Load unpacked extension` to load HostAdmin. You can get more help from [Getting Started: Building a Chrome Extension](https://developer.chrome.com/extensions/getstarted.html) 36 | 37 | 1. NPAPI (Optional) 38 | 39 | 40 | You may want edit NPAPI, you can find source at `npapi/src` 41 | * Build on Linux (gcc, Just make to build hostadmin.so) 42 | * Mac (open hostadmin.xcodeproj with XCode, Command + B to build hostadmin.plugin) 43 | * Windows (open hostadmin.sln with Visual Studio Express 2008, build .dll) 44 | 45 | 46 | 47 | Build Distributions 48 | ------------------- 49 | 50 | You can build .xpi(Firefox) and .zip(Chrome) using dist script. *Notice:* If you are building on Mac, you need `gnu coreutils` ratcher built-in `BSD coreutils`. 51 | 52 | 53 | Build all 54 | 55 | ./dist 56 | 57 | 58 | Clean up 59 | 60 | ./dist clean 61 | 62 | 63 | Sometimes, you may want .crx version. 64 | 65 | ./dist-chrome.sh crx 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License, version 2.0 2 | 3 | 1. Definitions 4 | 5 | 1.1. "Contributor" 6 | 7 | means each individual or legal entity that creates, contributes to the 8 | creation of, or owns Covered Software. 9 | 10 | 1.2. "Contributor Version" 11 | 12 | means the combination of the Contributions of others (if any) used by a 13 | Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | 17 | means Covered Software of a particular Contributor. 18 | 19 | 1.4. "Covered Software" 20 | 21 | means Source Code Form to which the initial Contributor has attached the 22 | notice in Exhibit A, the Executable Form of such Source Code Form, and 23 | Modifications of such Source Code Form, in each case including portions 24 | thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | a. that the initial Contributor has attached the notice described in 30 | Exhibit B to the Covered Software; or 31 | 32 | b. that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the terms of 34 | a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | 38 | means any form of the work other than Source Code Form. 39 | 40 | 1.7. "Larger Work" 41 | 42 | means a work that combines Covered Software with other material, in a 43 | separate file or files, that is not Covered Software. 44 | 45 | 1.8. "License" 46 | 47 | means this document. 48 | 49 | 1.9. "Licensable" 50 | 51 | means having the right to grant, to the maximum extent possible, whether 52 | at the time of the initial grant or subsequently, any and all of the 53 | rights conveyed by this License. 54 | 55 | 1.10. "Modifications" 56 | 57 | means any of the following: 58 | 59 | a. any file in Source Code Form that results from an addition to, 60 | deletion from, or modification of the contents of Covered Software; or 61 | 62 | b. any new file in Source Code Form that contains any Covered Software. 63 | 64 | 1.11. "Patent Claims" of a Contributor 65 | 66 | means any patent claim(s), including without limitation, method, 67 | process, and apparatus claims, in any patent Licensable by such 68 | Contributor that would be infringed, but for the grant of the License, 69 | by the making, using, selling, offering for sale, having made, import, 70 | or transfer of either its Contributions or its Contributor Version. 71 | 72 | 1.12. "Secondary License" 73 | 74 | means either the GNU General Public License, Version 2.0, the GNU Lesser 75 | General Public License, Version 2.1, the GNU Affero General Public 76 | License, Version 3.0, or any later versions of those licenses. 77 | 78 | 1.13. "Source Code Form" 79 | 80 | means the form of the work preferred for making modifications. 81 | 82 | 1.14. "You" (or "Your") 83 | 84 | means an individual or a legal entity exercising rights under this 85 | License. For legal entities, "You" includes any entity that controls, is 86 | controlled by, or is under common control with You. For purposes of this 87 | definition, "control" means (a) the power, direct or indirect, to cause 88 | the direction or management of such entity, whether by contract or 89 | otherwise, or (b) ownership of more than fifty percent (50%) of the 90 | outstanding shares or beneficial ownership of such entity. 91 | 92 | 93 | 2. License Grants and Conditions 94 | 95 | 2.1. Grants 96 | 97 | Each Contributor hereby grants You a world-wide, royalty-free, 98 | non-exclusive license: 99 | 100 | a. under intellectual property rights (other than patent or trademark) 101 | Licensable by such Contributor to use, reproduce, make available, 102 | modify, display, perform, distribute, and otherwise exploit its 103 | Contributions, either on an unmodified basis, with Modifications, or 104 | as part of a Larger Work; and 105 | 106 | b. under Patent Claims of such Contributor to make, use, sell, offer for 107 | sale, have made, import, and otherwise transfer either its 108 | Contributions or its Contributor Version. 109 | 110 | 2.2. Effective Date 111 | 112 | The licenses granted in Section 2.1 with respect to any Contribution 113 | become effective for each Contribution on the date the Contributor first 114 | distributes such Contribution. 115 | 116 | 2.3. Limitations on Grant Scope 117 | 118 | The licenses granted in this Section 2 are the only rights granted under 119 | this License. No additional rights or licenses will be implied from the 120 | distribution or licensing of Covered Software under this License. 121 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 122 | Contributor: 123 | 124 | a. for any code that a Contributor has removed from Covered Software; or 125 | 126 | b. for infringements caused by: (i) Your and any other third party's 127 | modifications of Covered Software, or (ii) the combination of its 128 | Contributions with other software (except as part of its Contributor 129 | Version); or 130 | 131 | c. under Patent Claims infringed by Covered Software in the absence of 132 | its Contributions. 133 | 134 | This License does not grant any rights in the trademarks, service marks, 135 | or logos of any Contributor (except as may be necessary to comply with 136 | the notice requirements in Section 3.4). 137 | 138 | 2.4. Subsequent Licenses 139 | 140 | No Contributor makes additional grants as a result of Your choice to 141 | distribute the Covered Software under a subsequent version of this 142 | License (see Section 10.2) or under the terms of a Secondary License (if 143 | permitted under the terms of Section 3.3). 144 | 145 | 2.5. Representation 146 | 147 | Each Contributor represents that the Contributor believes its 148 | Contributions are its original creation(s) or it has sufficient rights to 149 | grant the rights to its Contributions conveyed by this License. 150 | 151 | 2.6. Fair Use 152 | 153 | This License is not intended to limit any rights You have under 154 | applicable copyright doctrines of fair use, fair dealing, or other 155 | equivalents. 156 | 157 | 2.7. Conditions 158 | 159 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 160 | Section 2.1. 161 | 162 | 163 | 3. Responsibilities 164 | 165 | 3.1. Distribution of Source Form 166 | 167 | All distribution of Covered Software in Source Code Form, including any 168 | Modifications that You create or to which You contribute, must be under 169 | the terms of this License. You must inform recipients that the Source 170 | Code Form of the Covered Software is governed by the terms of this 171 | License, and how they can obtain a copy of this License. You may not 172 | attempt to alter or restrict the recipients' rights in the Source Code 173 | Form. 174 | 175 | 3.2. Distribution of Executable Form 176 | 177 | If You distribute Covered Software in Executable Form then: 178 | 179 | a. such Covered Software must also be made available in Source Code Form, 180 | as described in Section 3.1, and You must inform recipients of the 181 | Executable Form how they can obtain a copy of such Source Code Form by 182 | reasonable means in a timely manner, at a charge no more than the cost 183 | of distribution to the recipient; and 184 | 185 | b. You may distribute such Executable Form under the terms of this 186 | License, or sublicense it under different terms, provided that the 187 | license for the Executable Form does not attempt to limit or alter the 188 | recipients' rights in the Source Code Form under this License. 189 | 190 | 3.3. Distribution of a Larger Work 191 | 192 | You may create and distribute a Larger Work under terms of Your choice, 193 | provided that You also comply with the requirements of this License for 194 | the Covered Software. If the Larger Work is a combination of Covered 195 | Software with a work governed by one or more Secondary Licenses, and the 196 | Covered Software is not Incompatible With Secondary Licenses, this 197 | License permits You to additionally distribute such Covered Software 198 | under the terms of such Secondary License(s), so that the recipient of 199 | the Larger Work may, at their option, further distribute the Covered 200 | Software under the terms of either this License or such Secondary 201 | License(s). 202 | 203 | 3.4. Notices 204 | 205 | You may not remove or alter the substance of any license notices 206 | (including copyright notices, patent notices, disclaimers of warranty, or 207 | limitations of liability) contained within the Source Code Form of the 208 | Covered Software, except that You may alter any license notices to the 209 | extent required to remedy known factual inaccuracies. 210 | 211 | 3.5. Application of Additional Terms 212 | 213 | You may choose to offer, and to charge a fee for, warranty, support, 214 | indemnity or liability obligations to one or more recipients of Covered 215 | Software. However, You may do so only on Your own behalf, and not on 216 | behalf of any Contributor. You must make it absolutely clear that any 217 | such warranty, support, indemnity, or liability obligation is offered by 218 | You alone, and You hereby agree to indemnify every Contributor for any 219 | liability incurred by such Contributor as a result of warranty, support, 220 | indemnity or liability terms You offer. You may include additional 221 | disclaimers of warranty and limitations of liability specific to any 222 | jurisdiction. 223 | 224 | 4. Inability to Comply Due to Statute or Regulation 225 | 226 | If it is impossible for You to comply with any of the terms of this License 227 | with respect to some or all of the Covered Software due to statute, 228 | judicial order, or regulation then You must: (a) comply with the terms of 229 | this License to the maximum extent possible; and (b) describe the 230 | limitations and the code they affect. Such description must be placed in a 231 | text file included with all distributions of the Covered Software under 232 | this License. Except to the extent prohibited by statute or regulation, 233 | such description must be sufficiently detailed for a recipient of ordinary 234 | skill to be able to understand it. 235 | 236 | 5. Termination 237 | 238 | 5.1. The rights granted under this License will terminate automatically if You 239 | fail to comply with any of its terms. However, if You become compliant, 240 | then the rights granted under this License from a particular Contributor 241 | are reinstated (a) provisionally, unless and until such Contributor 242 | explicitly and finally terminates Your grants, and (b) on an ongoing 243 | basis, if such Contributor fails to notify You of the non-compliance by 244 | some reasonable means prior to 60 days after You have come back into 245 | compliance. Moreover, Your grants from a particular Contributor are 246 | reinstated on an ongoing basis if such Contributor notifies You of the 247 | non-compliance by some reasonable means, this is the first time You have 248 | received notice of non-compliance with this License from such 249 | Contributor, and You become compliant prior to 30 days after Your receipt 250 | of the notice. 251 | 252 | 5.2. If You initiate litigation against any entity by asserting a patent 253 | infringement claim (excluding declaratory judgment actions, 254 | counter-claims, and cross-claims) alleging that a Contributor Version 255 | directly or indirectly infringes any patent, then the rights granted to 256 | You by any and all Contributors for the Covered Software under Section 257 | 2.1 of this License shall terminate. 258 | 259 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 260 | license agreements (excluding distributors and resellers) which have been 261 | validly granted by You or Your distributors under this License prior to 262 | termination shall survive termination. 263 | 264 | 6. Disclaimer of Warranty 265 | 266 | Covered Software is provided under this License on an "as is" basis, 267 | without warranty of any kind, either expressed, implied, or statutory, 268 | including, without limitation, warranties that the Covered Software is free 269 | of defects, merchantable, fit for a particular purpose or non-infringing. 270 | The entire risk as to the quality and performance of the Covered Software 271 | is with You. Should any Covered Software prove defective in any respect, 272 | You (not any Contributor) assume the cost of any necessary servicing, 273 | repair, or correction. This disclaimer of warranty constitutes an essential 274 | part of this License. No use of any Covered Software is authorized under 275 | this License except under this disclaimer. 276 | 277 | 7. Limitation of Liability 278 | 279 | Under no circumstances and under no legal theory, whether tort (including 280 | negligence), contract, or otherwise, shall any Contributor, or anyone who 281 | distributes Covered Software as permitted above, be liable to You for any 282 | direct, indirect, special, incidental, or consequential damages of any 283 | character including, without limitation, damages for lost profits, loss of 284 | goodwill, work stoppage, computer failure or malfunction, or any and all 285 | other commercial damages or losses, even if such party shall have been 286 | informed of the possibility of such damages. This limitation of liability 287 | shall not apply to liability for death or personal injury resulting from 288 | such party's negligence to the extent applicable law prohibits such 289 | limitation. Some jurisdictions do not allow the exclusion or limitation of 290 | incidental or consequential damages, so this exclusion and limitation may 291 | not apply to You. 292 | 293 | 8. Litigation 294 | 295 | Any litigation relating to this License may be brought only in the courts 296 | of a jurisdiction where the defendant maintains its principal place of 297 | business and such litigation shall be governed by laws of that 298 | jurisdiction, without reference to its conflict-of-law provisions. Nothing 299 | in this Section shall prevent a party's ability to bring cross-claims or 300 | counter-claims. 301 | 302 | 9. Miscellaneous 303 | 304 | This License represents the complete agreement concerning the subject 305 | matter hereof. If any provision of this License is held to be 306 | unenforceable, such provision shall be reformed only to the extent 307 | necessary to make it enforceable. Any law or regulation which provides that 308 | the language of a contract shall be construed against the drafter shall not 309 | be used to construe this License against a Contributor. 310 | 311 | 312 | 10. Versions of the License 313 | 314 | 10.1. New Versions 315 | 316 | Mozilla Foundation is the license steward. Except as provided in Section 317 | 10.3, no one other than the license steward has the right to modify or 318 | publish new versions of this License. Each version will be given a 319 | distinguishing version number. 320 | 321 | 10.2. Effect of New Versions 322 | 323 | You may distribute the Covered Software under the terms of the version 324 | of the License under which You originally received the Covered Software, 325 | or under the terms of any subsequent version published by the license 326 | steward. 327 | 328 | 10.3. Modified Versions 329 | 330 | If you create software not governed by this License, and you want to 331 | create a new license for such software, you may create and use a 332 | modified version of this License if you rename the license and remove 333 | any references to the name of the license steward (except to note that 334 | such modified license differs from this License). 335 | 336 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 337 | Licenses If You choose to distribute Source Code Form that is 338 | Incompatible With Secondary Licenses under the terms of this version of 339 | the License, the notice described in Exhibit B of this License must be 340 | attached. 341 | 342 | Exhibit A - Source Code Form License Notice 343 | 344 | This Source Code Form is subject to the 345 | terms of the Mozilla Public License, v. 346 | 2.0. If a copy of the MPL was not 347 | distributed with this file, You can 348 | obtain one at 349 | http://mozilla.org/MPL/2.0/. 350 | 351 | If it is not possible or desirable to put the notice in a particular file, 352 | then You may include the notice in a location (such as a LICENSE file in a 353 | relevant directory) where a recipient would be likely to look for such a 354 | notice. 355 | 356 | You may add additional accurate notices of copyright ownership. 357 | 358 | Exhibit B - "Incompatible With Secondary Licenses" Notice 359 | 360 | This Source Code Form is "Incompatible 361 | With Secondary Licenses", as defined by 362 | the Mozilla Public License, v. 2.0. 363 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | HostAdmin 2 | ===================== 3 | Saving your time when you switch domain-ip mapping between different environment 4 | 5 | Chrome APP Version 6 | ------------------ 7 | Google banned NPAPI Please use [Chrome WebStore APP Version](https://chrome.google.com/webstore/detail/hostadmin-app/mfoaclfeiefiehgaojbmncmefhdnikeg) instead. 8 | 9 | It is true that is not easy to use than a menu bar edition. sad.. 10 | 11 | 12 | 13 | Installing 14 | ----------------------------- 15 | * [Chrome WebStore APP Version](https://chrome.google.com/webstore/detail/hostadmin-app/mfoaclfeiefiehgaojbmncmefhdnikeg) 16 | * [Firefox AddonSite](https://addons.mozilla.org/firefox/addon/hostadmin) 17 | * [Download from Google Code](http://code.google.com/p/fire-hostadmin/downloads/list) 18 | 19 | 20 | How HostAdmin analyze the Hosts file 21 | ------------------------------------ 22 | [Syntax detail](http://code.google.com/p/fire-hostadmin/wiki/HOST_SYNTAX) 23 | 24 | * ``Common`` 25 | 26 | IP DOMAIN [#COMMENT] 27 | 28 | *Example:* 29 | 30 | 127.0.0.1 localhost #comment here 31 | 32 | NOTE: A line with a comment, 'hide' (case-insensitive), would be hiden from HostAdmin. 33 | 34 | * ``Grouping`` 35 | 36 | #==== Groupname 37 | 38 | # some mappings 39 | 40 | #==== 41 | 42 | *Example:* 43 | 44 | #==== Project 1 45 | #127.0.0.1 localhost1 46 | 127.0.0.1 localhost2 47 | 127.0.0.1 localhost3 48 | #==== 49 | 50 | #==== Project 2 51 | #127.0.0.1 localhost1 52 | #127.0.0.1 localhost2 53 | #127.0.0.1 localhost3 54 | #==== 55 | 56 | 57 | * ``Bulk Hide`` 58 | 59 | 60 | #hide_all_of_below 61 | ... 62 | 63 | #All text here will be parsed as comment 64 | 65 | ... 66 | 67 | 68 | 69 | WRITE Permission to Hosts File 70 | ------------------------------ 71 | *WRITE Permission* to Hosts is needed, thus HostAdmin could modify your Host Files. 72 | XP users need NO additional setting. 73 | Here is a guide for you to gain write privilege for Vista/7/Linux/MacOS users 74 | 75 | http://code.google.com/p/fire-hostadmin/wiki/GAIN_HOSTS_WRITE_PERM 76 | 77 | DNS Auto refreshing 78 | ------------------- 79 | 80 | * ``Firefox`` 81 | 82 | HostAdmin borrowed code from [DNS flusher](https://addons.mozilla.org/en-US/firefox/addon/dns-flusher/) 83 | to refresh dns when hosts file is modified. 84 | 85 | * ``Chrome`` 86 | 87 | Since Chrome 21, Chrome will auto refresh dns by itself. 88 | More info at this [ticket](http://code.google.com/p/chromium/issues/detail?id=125599) 89 | 90 | > _KNOWN ISSUE_ 91 | > 92 | > DNS may not refresh as soon as hosts file changes due to a Chrome bug 93 | > reused socket pools by domain even if hosts changes 94 | > 95 | > To avoid this, open chrome://net-internals/#sockets and flush your host 96 | > 97 | > More info at Chrome Bug [152906](https://code.google.com/p/chromium/issues/detail?id=152906) [268059](https://code.google.com/p/chromium/issues/detail?id=268059) [288061](https://code.google.com/p/chromium/issues/detail?id=288061) 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /chrome.manifest: -------------------------------------------------------------------------------- 1 | content hostadmin-container container/firefox/ 2 | content hostadmin core/ 3 | content hostadmin-icons icons/ 4 | 5 | style chrome://global/content/customizeToolbar.xul chrome://hostadmin-container/content/hostadmin.css 6 | overlay chrome://browser/content/browser.xul chrome://hostadmin-container/content/hostadmin.xul 7 | -------------------------------------------------------------------------------- /container/chrome/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /container/chrome/config.js: -------------------------------------------------------------------------------- 1 | (function(HostAdmin){ 2 | 3 | var chrome_config = (function(){ 4 | return { 5 | set: function(key, value){ 6 | localStorage.setItem(key, JSON.stringify(value)); 7 | }, 8 | get: function(key){ 9 | return JSON. parse(localStorage.getItem(key));; 10 | } 11 | }; 12 | })(); 13 | 14 | HostAdmin.config = chrome_config; 15 | })(window.HostAdmin); 16 | -------------------------------------------------------------------------------- /container/chrome/container.js: -------------------------------------------------------------------------------- 1 | ;(function(HostAdmin){ 2 | 3 | var host_admin = HostAdmin.core; 4 | var event_host = HostAdmin.event_host; 5 | var cur_host; 6 | 7 | var opentab = function(t, line){ 8 | var url = null; 9 | if(t == 'EDITOR'){ 10 | url = chrome.runtime.getURL('core/editor.html'); 11 | }else if (t == 'PERMHELP'){ 12 | url = HostAdmin.PERM_HELP_URL; 13 | }else{ 14 | url = t; 15 | } 16 | 17 | if(url){ 18 | chrome.tabs.query({ url : url ,windowId: chrome.windows.WINDOW_ID_CURRENT }, function(t){ 19 | HostAdmin.cursorline = line; 20 | 21 | if (t.length > 0){ 22 | chrome.tabs.update(t[0].id, {active : true}); 23 | HostAdmin.requestCursorLine(line); 24 | }else{ 25 | chrome.tabs.create({url: url}); 26 | } 27 | 28 | }); 29 | } 30 | }; 31 | 32 | var hostreg = /:\/\/([\w\.\-]+)/; 33 | var extracthost = function(url){ 34 | if(url) { 35 | cur_host = url.match(hostreg)[1]; 36 | } 37 | updatelb(); 38 | 39 | }; 40 | 41 | var updatelb = function(){ 42 | var curHost = host_admin.real_hostname(cur_host); 43 | 44 | var str = ""; 45 | var hosts = host_admin.get_hosts(); 46 | if (typeof hosts[curHost] != "undefined") { 47 | hosts = hosts[curHost]; 48 | for (var i in hosts){ 49 | str = "*"; 50 | if(hosts[i].using){ 51 | str = hosts[i].addr + " " + hosts[i].comment; 52 | break; 53 | } 54 | } 55 | } 56 | 57 | chrome.browserAction.setBadgeBackgroundColor({color:'#0A0'}); 58 | chrome.browserAction.setBadgeText({text:str}); 59 | 60 | if(str == '*') { str = 'In Hosts';} 61 | else if( str === "" ) { str = 'Not In Hosts';} 62 | 63 | chrome.browserAction.setTitle({title: str}); 64 | 65 | }; 66 | 67 | chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){ 68 | extracthost(changeInfo.url); 69 | }); 70 | chrome.tabs.onActivated.addListener(function(activeInfo){ 71 | chrome.tabs.query({ active: true , windowType: "normal", windowId: chrome.windows.WINDOW_ID_CURRENT }, function(t){ 72 | if (t.length > 0){ 73 | extracthost(t[0].url); } 74 | }); 75 | }); 76 | 77 | HostAdmin.container = { 78 | opentab : opentab, 79 | curhost : function(){ return cur_host;} 80 | }; 81 | 82 | event_host.addEventListener('HostAdminRefresh', function(e) { 83 | updatelb(); 84 | chrome.browsingData.removeCache({}); 85 | }, false); 86 | })(window.HostAdmin); 87 | -------------------------------------------------------------------------------- /container/chrome/host_file_wrapper.js: -------------------------------------------------------------------------------- 1 | ;(function(HostAdmin){ 2 | 3 | var helper = document.getElementById("host_admin_helper"); 4 | var splitchar = "\n"; 5 | var os = helper.os; 6 | 7 | var file_name; 8 | if (os == "WINNT"){ 9 | splitchar = "\r\n"; 10 | file_name = helper.where + "\\drivers\\etc\\hosts"; 11 | }else if(os == "Linux"){ 12 | file_name = "/etc/hosts"; 13 | }else if(os == "Darwin"){ 14 | file_name = "/etc/hosts"; 15 | } 16 | 17 | HostAdmin.host_file_wrapper = { 18 | get : function(){ 19 | return helper.get(file_name); 20 | }, 21 | set : function(data){ 22 | if (os == "WINNT"){ 23 | data = data.replace(/([^\r])\n/g, "$1\r\n"); 24 | } 25 | return helper.set(file_name, data); 26 | }, 27 | time : function(){ 28 | return helper.time(file_name); 29 | }, 30 | splitchar : splitchar 31 | }; 32 | })(window.HostAdmin); 33 | -------------------------------------------------------------------------------- /container/chrome/timer.js: -------------------------------------------------------------------------------- 1 | ;(function(HostAdmin){ 2 | var host_admin = HostAdmin.core; 3 | 4 | HostAdmin.dontgc = setInterval(function(){ 5 | host_admin.refresh(); 6 | }, 1000); 7 | })(window.HostAdmin); 8 | -------------------------------------------------------------------------------- /container/firefox/config.js: -------------------------------------------------------------------------------- 1 | (function(HostAdmin){ 2 | 3 | var fire_config = (function(){ 4 | var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService); 5 | prefs = prefs.getBranch("extensions.hostadmin."); 6 | 7 | return { 8 | set: function(key, value){ 9 | if (typeof(value) === "boolean"){ 10 | prefs.setBoolPref(key, value); 11 | }else{ 12 | prefs.setComplexValue(key, Components.interfaces.nsISupportsString, value); 13 | } 14 | }, 15 | get: function(key){ 16 | var type = prefs.getPrefType(key); 17 | if (type == prefs.PREF_BOOL){ 18 | return prefs.getBoolPref(key); 19 | //}else if(type == prefs.PREF_INT) { // no such now 20 | }else if(type == prefs.PREF_STRING) { 21 | return prefs.getComplexValue(key, Components.interfaces.nsISupportsString).data; 22 | } 23 | return undefined; 24 | }, 25 | run_when_not_equal: function(key, value, f){ 26 | var v = this.get(key); 27 | if(v && v != value){ 28 | f(v); 29 | } 30 | } 31 | }; 32 | })(); 33 | 34 | HostAdmin.config = fire_config; 35 | })(window.HostAdmin); 36 | -------------------------------------------------------------------------------- /container/firefox/container.js: -------------------------------------------------------------------------------- 1 | ;(function(HostAdmin){ 2 | var EDITOR_URL = 'chrome://hostadmin/content/editor.html'; 3 | var PERM_HELP_URL = HostAdmin.PERM_HELP_URL; 4 | 5 | // {{{ copy from https://developer.mozilla.org/en-US/docs/Code_snippets/Tabbed_browser 6 | function openAndReuseOneTabPerURL(url) { 7 | var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] 8 | .getService(Components.interfaces.nsIWindowMediator); 9 | var browserEnumerator = wm.getEnumerator("navigator:browser"); 10 | 11 | // Check each browser instance for our URL 12 | var found = false; 13 | while (!found && browserEnumerator.hasMoreElements()) { 14 | var browserWin = browserEnumerator.getNext(); 15 | var tabbrowser = browserWin.gBrowser; 16 | 17 | // Check each tab of this browser instance 18 | var numTabs = tabbrowser.browsers.length; 19 | for (var index = 0; index < numTabs; index++) { 20 | var currentBrowser = tabbrowser.getBrowserAtIndex(index); 21 | //if (url == currentBrowser.currentURI.spec) { 22 | if (currentBrowser.currentURI.spec.indexOf(url) == 0) { 23 | 24 | // The URL is already opened. Select this tab. 25 | tabbrowser.selectedTab = tabbrowser.tabContainer.childNodes[index]; 26 | 27 | // Focus *this* browser-window 28 | browserWin.focus(); 29 | 30 | found = true; 31 | break; 32 | } 33 | } 34 | } 35 | 36 | // Our URL isn't open. Open it now. 37 | if (!found) { 38 | var recentWindow = wm.getMostRecentWindow("navigator:browser"); 39 | if (recentWindow) { 40 | // Use an existing browser window 41 | recentWindow.delayedOpenTab(url, null, null, null, null); 42 | } 43 | else { 44 | // No browser windows are open, so open a new one. 45 | window.open(url); 46 | } 47 | } 48 | } 49 | // }}} 50 | 51 | var cur_host = ""; 52 | 53 | var tabchange = function(e){ 54 | var browser = gBrowser.selectedBrowser; 55 | cur_host = browser.contentWindow.window.location.hostname; 56 | }; 57 | 58 | 59 | var opentab = function(t, line){ 60 | var url = null; 61 | if(t == 'EDITOR'){ 62 | url = EDITOR_URL; 63 | }else if (t == 'PERMHELP'){ 64 | url = PERM_HELP_URL; 65 | }else{ 66 | url = t; 67 | } 68 | 69 | if(url){ 70 | 71 | HostAdmin.cursorline = line; 72 | 73 | openAndReuseOneTabPerURL(url); 74 | document.getElementById("hostadmin-menu-panel").hidePopup(); 75 | 76 | HostAdmin.requestCursorLine(line) 77 | } 78 | }; 79 | 80 | HostAdmin.container = { 81 | opentab : opentab, 82 | curhost : function(){ return cur_host; } 83 | }; 84 | 85 | var popuphelper = { 86 | HostAdmin : HostAdmin 87 | }; 88 | var host_admin = HostAdmin.core; 89 | 90 | window.addEventListener('DOMWindowCreated', function(e){ 91 | if( 92 | e.target.documentURI.indexOf(document.getElementById('hostadmin-menu-content').getAttribute('src')) === 0 93 | || 94 | e.target.documentURI.indexOf(EDITOR_URL) === 0 95 | ){ 96 | e.target.defaultView.window.firefox = popuphelper; 97 | } 98 | }, true); 99 | 100 | window.addEventListener("load", function(){ 101 | gBrowser.tabContainer.addEventListener("TabOpen", tabchange, false); 102 | gBrowser.tabContainer.addEventListener("TabSelect", tabchange, false); 103 | gBrowser.tabContainer.addEventListener("TabAttrModified", tabchange, false); 104 | 105 | var button = document.getElementById('hostadmin-toolbar-button'); 106 | if(button) 107 | button.addEventListener('command', function(e){ 108 | var menucontent = document.getElementById('hostadmin-menu-content').contentWindow; 109 | menucontent.focus(); 110 | // TODO dup code from popup.js 111 | host_admin.refresh(); 112 | var $ = menucontent.window.$; 113 | var searchval = host_admin.real_hostname(cur_host); 114 | $("#search input").val(searchval).select().keyup(); 115 | }, false); 116 | }, false); 117 | 118 | 119 | })(window.HostAdmin); 120 | -------------------------------------------------------------------------------- /container/firefox/firstrun.js: -------------------------------------------------------------------------------- 1 | // HostAdmin 2 | // by T.G.(farmer1992@gmail.com) 3 | // 4 | // MPL v2 5 | // http://code.google.com/p/fire-hostadmin/ 6 | 7 | (function(HostAdmin){ 8 | // {{{ 9 | // copy from https://developer.mozilla.org/en/Code_snippets/Toolbar 10 | function installButton(toolbarId, id, afterId) { 11 | if (!document.getElementById(id)) { 12 | var toolbar = document.getElementById(toolbarId); 13 | 14 | // If no afterId is given, then append the item to the toolbar 15 | var before = null; 16 | if (afterId) { 17 | var elem = document.getElementById(afterId); 18 | if (elem && elem.parentNode == toolbar) 19 | before = elem.nextElementSibling; 20 | } 21 | 22 | toolbar.insertItem(id, before); 23 | toolbar.setAttribute("currentset", toolbar.currentSet); 24 | document.persist(toolbar.id, "currentset"); 25 | 26 | if (toolbarId == "addon-bar") 27 | toolbar.collapsed = false; 28 | } 29 | } 30 | // }}} 31 | 32 | 33 | var fire_config = HostAdmin.config; 34 | var firstrun = fire_config.get("firstrun"); 35 | 36 | if (firstrun) { 37 | fire_config.set("firstrun", false); 38 | window.addEventListener("load", function(){ 39 | installButton("nav-bar", "hostadmin-toolbar-button"); 40 | }, false); 41 | } 42 | 43 | })(window.HostAdmin); 44 | -------------------------------------------------------------------------------- /container/firefox/host_file_wrapper.js: -------------------------------------------------------------------------------- 1 | // HostAdmin 2 | // by T.G.(farmer1992@gmail.com) 3 | // 4 | // file wrapper module 5 | // enable hostadmin read and set hosts file 6 | // 7 | (function(HostAdmin){ 8 | 9 | // copy from io.js 10 | // http://kb.mozillazine.org/Dev_:_Extensions_:_Example_Code_:_File_IO_:_jsio 11 | var FileIO = { 12 | 13 | localfileCID : '@mozilla.org/file/local;1', 14 | localfileIID : Components.interfaces.nsIFile, 15 | 16 | finstreamCID : '@mozilla.org/network/file-input-stream;1', 17 | finstreamIID : Components.interfaces.nsIFileInputStream, 18 | 19 | foutstreamCID : '@mozilla.org/network/file-output-stream;1', 20 | foutstreamIID : Components.interfaces.nsIFileOutputStream, 21 | 22 | sinstreamCID : '@mozilla.org/scriptableinputstream;1', 23 | sinstreamIID : Components.interfaces.nsIScriptableInputStream, 24 | 25 | suniconvCID : '@mozilla.org/intl/scriptableunicodeconverter', 26 | suniconvIID : Components.interfaces.nsIScriptableUnicodeConverter, 27 | 28 | open : function(path) { 29 | try { 30 | var file = Components.classes[this.localfileCID] 31 | .createInstance(this.localfileIID); 32 | file.initWithPath(path); 33 | return file; 34 | } 35 | catch(e) { 36 | return false; 37 | } 38 | }, 39 | 40 | read : function(file, charset) { 41 | try { 42 | var data = new String(); 43 | var fiStream = Components.classes[this.finstreamCID] 44 | .createInstance(this.finstreamIID); 45 | var siStream = Components.classes[this.sinstreamCID] 46 | .createInstance(this.sinstreamIID); 47 | fiStream.init(file, 1, 0, false); 48 | siStream.init(fiStream); 49 | data += siStream.read(-1); 50 | siStream.close(); 51 | fiStream.close(); 52 | if (charset) { 53 | data = this.toUnicode(charset, data); 54 | } 55 | return data; 56 | } 57 | catch(e) { 58 | return false; 59 | } 60 | }, 61 | 62 | write : function(file, data, mode, charset) { 63 | try { 64 | var foStream = Components.classes[this.foutstreamCID] 65 | .createInstance(this.foutstreamIID); 66 | if (charset) { 67 | data = this.fromUnicode(charset, data); 68 | } 69 | var flags = 0x02 | 0x08 | 0x20; // wronly | create | truncate 70 | if (mode == 'a') { 71 | flags = 0x02 | 0x10; // wronly | append 72 | } 73 | foStream.init(file, flags, 0664, 0); 74 | foStream.write(data, data.length); 75 | // foStream.flush(); 76 | foStream.close(); 77 | return true; 78 | } 79 | catch(e) { 80 | return false; 81 | } 82 | }, 83 | 84 | create : function(file) { 85 | try { 86 | file.create(0x00, 0664); 87 | return true; 88 | } 89 | catch(e) { 90 | return false; 91 | } 92 | }, 93 | 94 | unlink : function(file) { 95 | try { 96 | file.remove(false); 97 | return true; 98 | } 99 | catch(e) { 100 | return false; 101 | } 102 | }, 103 | 104 | path : function(file) { 105 | try { 106 | return 'file:///' + file.path.replace(/\\/g, '\/') 107 | .replace(/^\s*\/?/, '').replace(/\ /g, '%20'); 108 | } 109 | catch(e) { 110 | return false; 111 | } 112 | }, 113 | 114 | toUnicode : function(charset, data) { 115 | try{ 116 | var uniConv = Components.classes[this.suniconvCID] 117 | .createInstance(this.suniconvIID); 118 | uniConv.charset = charset; 119 | data = uniConv.ConvertToUnicode(data); 120 | } 121 | catch(e) { 122 | // foobar! 123 | } 124 | return data; 125 | }, 126 | 127 | fromUnicode : function(charset, data) { 128 | try { 129 | var uniConv = Components.classes[this.suniconvCID] 130 | .createInstance(this.suniconvIID); 131 | uniConv.charset = charset; 132 | data = uniConv.ConvertFromUnicode(data); 133 | // data += uniConv.Finish(); 134 | } 135 | catch(e) { 136 | // foobar! 137 | } 138 | return data; 139 | } 140 | 141 | }; 142 | 143 | var fire_config = HostAdmin.config; 144 | 145 | var host_file_wrapper = (function(){ 146 | const os = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS; 147 | var splitchar = "\n"; 148 | 149 | 150 | var file_names = []; 151 | 152 | fire_config.run_when_not_equal("hostsfilepath", "default", function(configpath){ 153 | file_names.push(configpath); 154 | }); 155 | 156 | if (os == "WINNT"){ 157 | splitchar = "\r\n"; 158 | try { 159 | var winDir = Components.classes["@mozilla.org/file/directory_service;1"]. 160 | getService(Components.interfaces.nsIProperties).get("WinD", Components.interfaces.nsIFile); 161 | file_names.push(winDir.path + "\\system32\\drivers\\etc\\hosts"); 162 | } 163 | catch (err) {} 164 | 165 | file_names.push("C:\\windows\\system32\\drivers\\etc\\hosts"); 166 | }else if(os == "Linux"){ 167 | file_names.push("/etc/hosts"); 168 | }else if(os == "Darwin"){ 169 | file_names.push("/etc/hosts"); 170 | } 171 | 172 | var file_name; 173 | for(var i in file_names){ 174 | file_name = file_names[i]; 175 | var _f = FileIO.open(file_name); 176 | if(_f && _f.exists()){ 177 | break; 178 | } 179 | } 180 | 181 | var charset = "utf8"; // null means auto 182 | 183 | // detect using jschardet 184 | // but maybe unqualified 185 | if(!charset){ 186 | // -- temp for windows before charset detector 187 | if (os == "WINNT"){ 188 | charset = 'gbk'; 189 | } 190 | 191 | //var file = FileIO.open(file_name); 192 | //charset = jschardet.detect(FileIO.read(file)); 193 | //charset = charset ? charset.encoding : "utf8"; 194 | } 195 | 196 | fire_config.run_when_not_equal("charset", "auto", function(c){ 197 | charset = c; 198 | }); 199 | 200 | return { 201 | get : function(){ 202 | var file = FileIO.open(file_name); 203 | return FileIO.read(file, charset); 204 | } 205 | , 206 | set : function(data){ 207 | if (os == "WINNT"){ 208 | data = data.replace(/([^\r])\n/g, "$1\r\n"); 209 | } 210 | 211 | var file = FileIO.open(file_name); 212 | return FileIO.write(file, data, '', charset); 213 | } 214 | , 215 | time : function(){ 216 | var file = FileIO.open(file_name); 217 | return file.lastModifiedTime; 218 | } 219 | , 220 | splitchar : splitchar 221 | }; 222 | })(); 223 | 224 | HostAdmin.host_file_wrapper = host_file_wrapper; 225 | })(window.HostAdmin); 226 | -------------------------------------------------------------------------------- /container/firefox/hostadmin.css: -------------------------------------------------------------------------------- 1 | #hostadmin-toolbar-button 2 | { 3 | list-style-image: url("chrome://hostadmin-icons/content/icon32.png"); 4 | } 5 | [iconsize="small"] #hostadmin-toolbar-button 6 | { 7 | list-style-image: url("chrome://hostadmin-icons/content/icon16.png"); 8 | } 9 | 10 | #hostadmin-menu-content{ 11 | margin:0; 12 | padding:0; 13 | border:0; 14 | } 15 | #hostadmin-menu-panel{ 16 | width:322px; 17 | height:600px; 18 | margin:0; 19 | padding:0; 20 | border:0; 21 | } 22 | -------------------------------------------------------------------------------- /container/firefox/hostadmin.xul: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 58 | 59 | 60 |
61 | 62 |

HostAdmin Host Editor

63 |
64 | Write hosts file failed check permissions, Learn more 65 |
66 |
67 |
68 |
69 |
70 | 79 |
80 |
81 |
82 |
83 |

Common Hosts File Syntax

84 |
 85 |   [#] <IP> <HOSTNAME_1> [<HOSTNAME_2>] [# COMMENT]
 86 | 
87 |

Note

88 |

Setting facultative [COMMENT] with 'hide' word prevents this line to be managed by HostAdmin and will not be displayed on quick edit tool.

89 | 90 |

Example

91 |
 92 |   127.0.0.1 localhost # hide
 93 | 
94 |
95 |
96 |

Grouping

97 |
 98 | #==== GROUPNAME
 99 |   [#] <IP_2>	<HOSTNAME_2> [<HOSTNAME_3>] [# COMMENT]
100 |   [#] <IP_3>	<HOSTNAME_4> [<HOSTNAME_5>] [# COMMENT]
101 |   [...]
102 | #====
103 | 
104 |

Example

105 |
106 | #==== Project 1
107 |   #127.0.0.1	localhost1
108 |   127.0.0.1	localhost2
109 |   127.0.0.1	localhost3
110 | #====
111 | 
112 | #==== Project 2
113 |   #127.0.0.1	localhost1
114 |   #127.0.0.1	localhost2
115 |   #127.0.0.1	localhost3
116 | #====
117 | 
118 |

Note

119 |

Grouping "hosts lines" let you enable/disable all records in group just clicking group name into "quick edit tool" in the bottom. These lines will have also a tag that will display the group name of appurtenance.

120 |
121 |
122 |

Bulk Hide

123 |
124 | #hide_all_of_below
125 | ....
126 | #All text here will be parsed as comment
127 | ....
128 | 
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |

139 |
Hosts file
   140 |

141 |
142 |
143 |
144 | 145 |
146 |
147 |
148 |
149 | 155 |
156 | 165 | 166 | 167 | Fork me on GitHub 168 | 169 | 170 | -------------------------------------------------------------------------------- /core/editor.js: -------------------------------------------------------------------------------- 1 | run_from_glue(function(HostAdmin){ 2 | var host_admin = HostAdmin.core; 3 | var event_host = HostAdmin.event_host; 4 | 5 | var container = HostAdmin.container; 6 | var opentab = container.opentab; 7 | 8 | var changed = false; 9 | var codeMirror = CodeMirror.fromTextArea(document.getElementById("code"), { 10 | lineNumbers: true, 11 | styleActiveLine: true 12 | }); 13 | 14 | var save = $("#btnSave"); 15 | 16 | codeMirror.on("change", function(){ 17 | changed = true; 18 | save.attr("disabled", null); 19 | }); 20 | 21 | codeMirror.setValue(host_admin.load()); 22 | 23 | var move_cursor = function(cursorline){ 24 | if(cursorline || cursorline === 0){ 25 | codeMirror.setCursor(cursorline); 26 | codeMirror.scrollIntoView({line: cursorline}, 150); 27 | codeMirror.focus(); 28 | } 29 | } 30 | 31 | move_cursor(HostAdmin.cursorline); 32 | 33 | var renew = function(){ 34 | changed = false; 35 | save.attr("disabled", "disabled"); 36 | $(".alert").hide('slow'); 37 | }; 38 | 39 | var reload = function(){ 40 | var pos = codeMirror.getScrollInfo() 41 | codeMirror.setValue(host_admin.load()); 42 | renew(); 43 | codeMirror.scrollTo(pos.left, pos.top); 44 | }; 45 | 46 | $("#mreload").click(function(){ 47 | $("#contentchanged").modal('hide'); 48 | 49 | reload(); 50 | }); 51 | 52 | event_host.addEventListener('HostAdminRefresh', function(e) { 53 | if(!changed){ 54 | reload(); 55 | }else{ 56 | $("#contentchanged").modal('show'); 57 | } 58 | }, false); 59 | 60 | 61 | event_host.addEventListener('HostAdminReqCursorLine', function(e) { 62 | move_cursor(e.detail.cursorline); 63 | }, false); 64 | 65 | save.click(function(e) { 66 | if(changed){ 67 | changed = false; 68 | 69 | var pos = codeMirror.getScrollInfo() 70 | 71 | if(host_admin.save(codeMirror.getValue())){ 72 | renew(); 73 | codeMirror.scrollTo(pos.left, pos.top); 74 | }else{ 75 | $(".alert").show('slow'); 76 | } 77 | } 78 | }); 79 | 80 | $(document).keydown(function(event){ 81 | if (event.which == 83 && (event.ctrlKey||event.metaKey)) { 82 | event.preventDefault(); 83 | save.click(); 84 | return false; 85 | } 86 | return true; 87 | }); 88 | 89 | $(".alert a").click(function(){ 90 | opentab('PERMHELP'); 91 | }); 92 | 93 | renew(); 94 | 95 | }); 96 | -------------------------------------------------------------------------------- /core/glue.js: -------------------------------------------------------------------------------- 1 | // 2 | // finding a method to be injected from container ... 3 | // 4 | window.run_from_glue = (function(){ 5 | 6 | var HostAdmin = null; 7 | 8 | if(typeof(chrome) == 'object'){ 9 | HostAdmin = chrome.extension.getBackgroundPage().HostAdmin; 10 | }else if(typeof(firefox) == 'object'){ 11 | HostAdmin = firefox.HostAdmin; 12 | } 13 | 14 | var _inner = function(callback){ 15 | callback(HostAdmin); 16 | }; 17 | 18 | return function(_callback){ 19 | _inner( _callback ); 20 | }; 21 | })(); 22 | -------------------------------------------------------------------------------- /core/hostadmin.js: -------------------------------------------------------------------------------- 1 | // HostAdmin 2 | // by T.G.(farmer1992@gmail.com) 3 | // 4 | // core module 5 | // implentment of hostadmin syntax 6 | // http://code.google.com/p/fire-hostadmin/wiki/HOST_SYNTAX 7 | // 8 | (function(HostAdmin){ 9 | 10 | var host_file_wrapper = HostAdmin.host_file_wrapper; 11 | var event_host = HostAdmin.event_host; 12 | 13 | var host_admin = (function(){ 14 | var ip_regx = /^((1?\d?\d|(2([0-4]\d|5[0-5])))\.){3}(1?\d?\d|(2([0-4]\d|5[0-5])))$/; 15 | 16 | // copy from http://forums.intermapper.com/viewtopic.php?t=452 17 | var ip6_regx = /^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?$/ ; 18 | 19 | var lines = []; 20 | var hosts = {}; 21 | var groups = {}; 22 | var hostname_withoutcase = {}; 23 | 24 | var cur_host_content = ""; 25 | 26 | var loadhost = function() { 27 | 28 | lines = []; 29 | hosts = {}; 30 | groups = {}; 31 | hostname_withoutcase = {}; 32 | //read 33 | var host = host_file_wrapper.get(); 34 | cur_host_content = host; 35 | 36 | if (host && host.charAt(host.length - 1) != "\n"){ //fix no lf 37 | host += host_file_wrapper.splitchar; 38 | } 39 | 40 | var l_p = 0; //pointer to line 41 | var regx = /(.*?)\r?\n/mg; 42 | var group_id = 0; 43 | var group_c = 0; 44 | var ingroup = false; 45 | var bulk_hide = false; 46 | var group_hided = {}; 47 | 48 | while(true){ 49 | var l = regx.exec(host); 50 | if(!l){ 51 | break; 52 | } 53 | 54 | var i; 55 | l = l[0]; 56 | 57 | lines[l_p++] = l; 58 | 59 | l = l.replace(/^(\s*#)+/,"#"); 60 | l = l.replace(/#/g," # "); 61 | l = l.replace(/^\s+|\s+$/g,""); 62 | l = l.replace(/\s+/g," "); 63 | 64 | var tks = l.split(" "); 65 | 66 | if (tks[0] == "#" && tks[1] == "===="){ 67 | if(group_c === 0){ 68 | group_id++; 69 | } 70 | 71 | if(group_c++ % 2 === 0){ 72 | tks.splice(0,2); 73 | var group_name = ""; 74 | for(i in tks){ 75 | group_name += tks[i] + " "; 76 | } 77 | 78 | if( tks[i-1] === "#" && tks[i].toUpperCase() == 'HIDE' ){ 79 | group_hided[group_id] = true; 80 | } 81 | 82 | if(group_name === ""){ 83 | group_name = "Group " + group_id; 84 | } 85 | 86 | groups[group_id] = group_name; 87 | ingroup = true; 88 | }else{ 89 | ingroup = false; 90 | group_id++; 91 | } 92 | continue; 93 | 94 | } else if (tks[0] == "#" && tks[1] && tks[1].toUpperCase() == "HIDE_ALL_OF_BELOW"){ 95 | bulk_hide = true; 96 | } 97 | 98 | var using = true; 99 | if (tks[0] == "#"){ 100 | using = false; 101 | tks.splice(0,1); 102 | } 103 | 104 | var ip = ""; 105 | if (ip_regx.test(tks[0]) || ip6_regx.test(tks[0])){ 106 | ip = tks[0]; 107 | tks.splice(0,1); 108 | }else{ 109 | continue; 110 | } 111 | 112 | var comment = ""; 113 | 114 | var names = []; 115 | var findc = false; 116 | var findhide = false; 117 | for (i in tks){ 118 | if(tks[i] == "#"){ 119 | findc = true; 120 | continue; 121 | } 122 | 123 | findhide = tks[i].toUpperCase() == 'HIDE' 124 | 125 | if(findc){ 126 | comment += tks[i] + " "; 127 | }else{ 128 | names.push(tks[i]); 129 | } 130 | } 131 | 132 | if(typeof(comment) == "string"){ 133 | comment = comment.replace(/^\s+|\s+$/g, ''); 134 | } 135 | 136 | ip = { 137 | addr : ip, 138 | using : using , 139 | line : l_p - 1, 140 | comment : comment, 141 | group : ingroup ? group_id : 0, 142 | hide : bulk_hide || findhide || (ingroup && group_hided[group_id] === true) 143 | }; 144 | 145 | for (i in names){ 146 | var name = names[i]; 147 | if(typeof hosts[name] == "undefined"){ 148 | hosts[name] = []; 149 | } 150 | 151 | hosts[name].push(ip); 152 | hostname_withoutcase[name.toUpperCase()] = name; 153 | } 154 | } 155 | }; 156 | 157 | var line_enable = function(ip){ 158 | if(!ip.using){ 159 | lines[ip.line] = lines[ip.line].replace(/^(\s*#)+/,""); 160 | } 161 | ip.using = true; 162 | }; 163 | 164 | var line_disable = function(ip){ 165 | if(ip.using){ 166 | lines[ip.line] = "#" + lines[ip.line]; 167 | } 168 | ip.using = false; 169 | }; 170 | 171 | var host_toggle = function(host_name, ip_p){ 172 | if(hosts[host_name]){ 173 | var addr = hosts[host_name][ip_p].addr; 174 | var using = hosts[host_name][ip_p].using; 175 | for (var i in hosts[host_name]){ 176 | var ip = hosts[host_name][i]; 177 | 178 | if(ip.addr == addr && !using){ 179 | line_enable(ip); 180 | }else{ 181 | line_disable(ip); 182 | } 183 | } 184 | } 185 | }; 186 | 187 | var is_group_all_using = function(host_list, gp_p){ 188 | for(var h in host_list){ 189 | for (var i in hosts[host_list[h]]){ 190 | var ip = hosts[host_list[h]][i]; 191 | if(ip.group == gp_p && !ip.using){ 192 | return false; 193 | } 194 | } 195 | } 196 | return true; 197 | }; 198 | 199 | var group_toggle = function(host_list, gp_p){ 200 | var using = is_group_all_using(host_list, gp_p); 201 | 202 | for(var h in host_list){ 203 | for (var i in hosts[host_list[h]]){ 204 | var ip = hosts[host_list[h]][i]; 205 | 206 | if(ip.group == gp_p){ 207 | if(using){ 208 | line_disable(ip); 209 | }else{ 210 | line_enable(ip); 211 | } 212 | }else if(ip.using){ 213 | line_disable(ip); 214 | } 215 | } 216 | } 217 | }; 218 | 219 | var mk_host = function(){ 220 | var str = ""; 221 | for (var i in lines){ 222 | str += lines[i]; 223 | } 224 | return str; 225 | }; 226 | 227 | var last_modify = 0; 228 | 229 | // {{{ 230 | 231 | var disp_refresh_event = function(){ 232 | var e = event_host.createEvent('Events'); 233 | e.initEvent('HostAdminRefresh', false, false); 234 | event_host.dispatchEvent(e); 235 | }; 236 | 237 | var last_host_content; 238 | var refresh = function(){ 239 | var t = host_file_wrapper.time(); 240 | 241 | if( t != last_modify){ 242 | loadhost(); 243 | 244 | if(last_host_content != cur_host_content){ 245 | // prevent from saving failed cause editor refresh 246 | last_host_content = cur_host_content; 247 | disp_refresh_event(); 248 | } 249 | 250 | last_modify = t; 251 | 252 | return true; 253 | } 254 | return false; 255 | }; 256 | // }}} 257 | 258 | return { 259 | get_hosts : function(){ 260 | return hosts; 261 | }, 262 | get_groups : function(){ 263 | return groups; 264 | }, 265 | host_toggle : host_toggle, 266 | group_toggle : group_toggle, 267 | group_checked : is_group_all_using, 268 | // mk_host : mk_host, 269 | 270 | host_toggle_and_save : function(host_name, ip_p){ 271 | host_toggle(host_name, ip_p); 272 | return this.save(); 273 | } , 274 | group_toggle_and_save : function(host_list, gp_p){ 275 | group_toggle(host_list, gp_p); 276 | return this.save(); 277 | }, 278 | save : function(hoststr){ 279 | if(!hoststr){ hoststr = mk_host();} 280 | 281 | var succ = host_file_wrapper.set(hoststr); 282 | 283 | last_modify = 0; 284 | this.refresh(); 285 | return succ; 286 | }, 287 | 288 | load : function(){ 289 | return cur_host_content; 290 | }, 291 | 292 | refresh : refresh, 293 | 294 | real_hostname: function(hostname){ 295 | if(hostname) return hostname_withoutcase[hostname.toUpperCase()]; 296 | } 297 | 298 | }; 299 | 300 | })(); 301 | 302 | HostAdmin.core = host_admin; 303 | HostAdmin.PERM_HELP_URL = 'http://code.google.com/p/fire-hostadmin/wiki/GAIN_HOSTS_WRITE_PERM'; 304 | })(window.HostAdmin); 305 | 306 | -------------------------------------------------------------------------------- /core/init.js: -------------------------------------------------------------------------------- 1 | // HostAdmin 2 | // by T.G.(farmer1992@gmail.com) 3 | // 4 | // MPL v2 5 | // http://code.google.com/p/fire-hostadmin/ 6 | window.HostAdmin = {}; 7 | 8 | // event and cursor 9 | (function(HostAdmin){ 10 | HostAdmin.event_host = document; 11 | 12 | HostAdmin.requestCursorLine = function(line){ 13 | if(line || line === 0){ 14 | var e = HostAdmin.event_host.createEvent('CustomEvent'); 15 | e.initCustomEvent('HostAdminReqCursorLine', false, false, { cursorline : line }); 16 | HostAdmin.event_host.dispatchEvent(e); 17 | } 18 | } 19 | })(window.HostAdmin); 20 | 21 | -------------------------------------------------------------------------------- /core/lib/CodeMirror/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 by Marijn Haverbeke 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | Please note that some subdirectories of the CodeMirror distribution 22 | include their own LICENSE files, and are released under different 23 | licences. 24 | -------------------------------------------------------------------------------- /core/lib/CodeMirror/addon/selection/active-line.js: -------------------------------------------------------------------------------- 1 | // Because sometimes you need to style the cursor's line. 2 | // 3 | // Adds an option 'styleActiveLine' which, when enabled, gives the 4 | // active line's wrapping
the CSS class "CodeMirror-activeline", 5 | // and gives its background
the class "CodeMirror-activeline-background". 6 | 7 | (function() { 8 | "use strict"; 9 | var WRAP_CLASS = "CodeMirror-activeline"; 10 | var BACK_CLASS = "CodeMirror-activeline-background"; 11 | 12 | CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { 13 | var prev = old && old != CodeMirror.Init; 14 | if (val && !prev) { 15 | updateActiveLine(cm); 16 | cm.on("cursorActivity", updateActiveLine); 17 | } else if (!val && prev) { 18 | cm.off("cursorActivity", updateActiveLine); 19 | clearActiveLine(cm); 20 | delete cm._activeLine; 21 | } 22 | }); 23 | 24 | function clearActiveLine(cm) { 25 | if ("_activeLine" in cm) { 26 | cm.removeLineClass(cm._activeLine, "wrap", WRAP_CLASS); 27 | cm.removeLineClass(cm._activeLine, "background", BACK_CLASS); 28 | } 29 | } 30 | 31 | function updateActiveLine(cm) { 32 | var line = cm.getLineHandle(cm.getCursor().line); 33 | if (cm._activeLine == line) return; 34 | clearActiveLine(cm); 35 | cm.addLineClass(line, "wrap", WRAP_CLASS); 36 | cm.addLineClass(line, "background", BACK_CLASS); 37 | cm._activeLine = line; 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /core/lib/CodeMirror/lib/codemirror.css: -------------------------------------------------------------------------------- 1 | /* BASICS */ 2 | 3 | .CodeMirror { 4 | /* Set height, width, borders, and global font properties here */ 5 | font-family: monospace; 6 | height: 300px; 7 | } 8 | .CodeMirror-scroll { 9 | /* Set scrolling behaviour here */ 10 | overflow: auto; 11 | } 12 | 13 | /* PADDING */ 14 | 15 | .CodeMirror-lines { 16 | padding: 4px 0; /* Vertical padding around content */ 17 | } 18 | .CodeMirror pre { 19 | padding: 0 4px; /* Horizontal padding of content */ 20 | } 21 | 22 | .CodeMirror-scrollbar-filler { 23 | background-color: white; /* The little square between H and V scrollbars */ 24 | } 25 | 26 | /* GUTTER */ 27 | 28 | .CodeMirror-gutters { 29 | border-right: 1px solid #ddd; 30 | background-color: #f7f7f7; 31 | } 32 | .CodeMirror-linenumbers {} 33 | .CodeMirror-linenumber { 34 | padding: 0 3px 0 5px; 35 | min-width: 20px; 36 | text-align: right; 37 | color: #999; 38 | } 39 | 40 | /* CURSOR */ 41 | 42 | .CodeMirror pre.CodeMirror-cursor { 43 | border-left: 1px solid black; 44 | } 45 | /* Shown when moving in bi-directional text */ 46 | .CodeMirror pre.CodeMirror-secondarycursor { 47 | border-left: 1px solid silver; 48 | } 49 | .cm-keymap-fat-cursor pre.CodeMirror-cursor { 50 | width: auto; 51 | border: 0; 52 | background: transparent; 53 | background: rgba(0, 200, 0, .4); 54 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800); 55 | } 56 | /* Kludge to turn off filter in ie9+, which also accepts rgba */ 57 | .cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) { 58 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 59 | } 60 | /* Can style cursor different in overwrite (non-insert) mode */ 61 | .CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {} 62 | 63 | /* DEFAULT THEME */ 64 | 65 | .cm-s-default .cm-keyword {color: #708;} 66 | .cm-s-default .cm-atom {color: #219;} 67 | .cm-s-default .cm-number {color: #164;} 68 | .cm-s-default .cm-def {color: #00f;} 69 | .cm-s-default .cm-variable {color: black;} 70 | .cm-s-default .cm-variable-2 {color: #05a;} 71 | .cm-s-default .cm-variable-3 {color: #085;} 72 | .cm-s-default .cm-property {color: black;} 73 | .cm-s-default .cm-operator {color: black;} 74 | .cm-s-default .cm-comment {color: #a50;} 75 | .cm-s-default .cm-string {color: #a11;} 76 | .cm-s-default .cm-string-2 {color: #f50;} 77 | .cm-s-default .cm-meta {color: #555;} 78 | .cm-s-default .cm-error {color: #f00;} 79 | .cm-s-default .cm-qualifier {color: #555;} 80 | .cm-s-default .cm-builtin {color: #30a;} 81 | .cm-s-default .cm-bracket {color: #997;} 82 | .cm-s-default .cm-tag {color: #170;} 83 | .cm-s-default .cm-attribute {color: #00c;} 84 | .cm-s-default .cm-header {color: blue;} 85 | .cm-s-default .cm-quote {color: #090;} 86 | .cm-s-default .cm-hr {color: #999;} 87 | .cm-s-default .cm-link {color: #00c;} 88 | 89 | .cm-negative {color: #d44;} 90 | .cm-positive {color: #292;} 91 | .cm-header, .cm-strong {font-weight: bold;} 92 | .cm-em {font-style: italic;} 93 | .cm-emstrong {font-style: italic; font-weight: bold;} 94 | .cm-link {text-decoration: underline;} 95 | 96 | .cm-invalidchar {color: #f00;} 97 | 98 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} 99 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} 100 | 101 | /* STOP */ 102 | 103 | /* The rest of this file contains styles related to the mechanics of 104 | the editor. You probably shouldn't touch them. */ 105 | 106 | .CodeMirror { 107 | line-height: 1; 108 | position: relative; 109 | overflow: hidden; 110 | } 111 | 112 | .CodeMirror-scroll { 113 | /* 30px is the magic margin used to hide the element's real scrollbars */ 114 | /* See overflow: hidden in .CodeMirror, and the paddings in .CodeMirror-sizer */ 115 | margin-bottom: -30px; margin-right: -30px; 116 | padding-bottom: 30px; padding-right: 30px; 117 | height: 100%; 118 | outline: none; /* Prevent dragging from highlighting the element */ 119 | position: relative; 120 | } 121 | .CodeMirror-sizer { 122 | position: relative; 123 | } 124 | 125 | /* The fake, visible scrollbars. Used to force redraw during scrolling 126 | before actuall scrolling happens, thus preventing shaking and 127 | flickering artifacts. */ 128 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler { 129 | position: absolute; 130 | z-index: 6; 131 | display: none; 132 | } 133 | .CodeMirror-vscrollbar { 134 | right: 0; top: 0; 135 | overflow-x: hidden; 136 | overflow-y: scroll; 137 | } 138 | .CodeMirror-hscrollbar { 139 | bottom: 0; left: 0; 140 | overflow-y: hidden; 141 | overflow-x: scroll; 142 | } 143 | .CodeMirror-scrollbar-filler { 144 | right: 0; bottom: 0; 145 | z-index: 6; 146 | } 147 | 148 | .CodeMirror-gutters { 149 | position: absolute; left: 0; top: 0; 150 | height: 100%; 151 | z-index: 3; 152 | } 153 | .CodeMirror-gutter { 154 | height: 100%; 155 | display: inline-block; 156 | /* Hack to make IE7 behave */ 157 | *zoom:1; 158 | *display:inline; 159 | } 160 | .CodeMirror-gutter-elt { 161 | position: absolute; 162 | cursor: default; 163 | z-index: 4; 164 | } 165 | 166 | .CodeMirror-lines { 167 | cursor: text; 168 | } 169 | .CodeMirror pre { 170 | /* Reset some styles that the rest of the page might have set */ 171 | -moz-border-radius: 0; -webkit-border-radius: 0; -o-border-radius: 0; border-radius: 0; 172 | border-width: 0; 173 | background: transparent; 174 | font-family: inherit; 175 | font-size: inherit; 176 | margin: 0; 177 | white-space: pre; 178 | word-wrap: normal; 179 | line-height: inherit; 180 | color: inherit; 181 | z-index: 2; 182 | position: relative; 183 | overflow: visible; 184 | } 185 | .CodeMirror-wrap pre { 186 | word-wrap: break-word; 187 | white-space: pre-wrap; 188 | word-break: normal; 189 | } 190 | .CodeMirror-linebackground { 191 | position: absolute; 192 | left: 0; right: 0; top: 0; bottom: 0; 193 | z-index: 0; 194 | } 195 | 196 | .CodeMirror-linewidget { 197 | position: relative; 198 | z-index: 2; 199 | } 200 | 201 | .CodeMirror-wrap .CodeMirror-scroll { 202 | overflow-x: hidden; 203 | } 204 | 205 | .CodeMirror-measure { 206 | position: absolute; 207 | width: 100%; height: 0px; 208 | overflow: hidden; 209 | visibility: hidden; 210 | } 211 | .CodeMirror-measure pre { position: static; } 212 | 213 | .CodeMirror pre.CodeMirror-cursor { 214 | position: absolute; 215 | visibility: hidden; 216 | border-right: none; 217 | width: 0; 218 | } 219 | .CodeMirror-focused pre.CodeMirror-cursor { 220 | visibility: visible; 221 | } 222 | 223 | .CodeMirror-selected { background: #d9d9d9; } 224 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } 225 | 226 | .CodeMirror-searching { 227 | background: #ffa; 228 | background: rgba(255, 255, 0, .4); 229 | } 230 | 231 | /* IE7 hack to prevent it from returning funny offsetTops on the spans */ 232 | .CodeMirror span { *vertical-align: text-bottom; } 233 | 234 | @media print { 235 | /* Hide the cursor when printing */ 236 | .CodeMirror pre.CodeMirror-cursor { 237 | visibility: hidden; 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /core/lib/CodeMirror/mode/hostadmin/hostadmin.js: -------------------------------------------------------------------------------- 1 | CodeMirror.defineMode("hostadmin", function(config, parserConfig) { 2 | var ipv4 = /^((1?\d?\d|(2([0-4]\d|5[0-5])))\.){3}(1?\d?\d|(2([0-4]\d|5[0-5])))\s/; 3 | var ipv6 = /^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s/ ; 4 | 5 | return { 6 | startState: function() {return { 7 | hasIp: false, 8 | groupline: false, 9 | groupid: 0 10 | };}, 11 | 12 | token: function(stream, state) { 13 | if(stream.sol()){ 14 | state.hasIP = false; 15 | state.groupline = false; 16 | } 17 | 18 | if(state.hide_all_of_below){ 19 | stream.skipToEnd(); 20 | return "comment"; 21 | } 22 | 23 | //stream.eatSpace(); 24 | var ch = stream.peek(); 25 | if (ch == "#") { 26 | if(stream.match(/#====\s/) || stream.match(/#====$/) ){ 27 | state.groupline = !stream.eol(); 28 | state.groupid++; 29 | 30 | return "keyword"; 31 | } 32 | 33 | stream.eatWhile(/[#\s]/); 34 | if(!state.hasIP && (stream.match(ipv4, false) || stream.match(ipv6, false))){ 35 | state.hasIP = true; 36 | return "keyword"; 37 | } 38 | 39 | if(stream.match(/^\s*hide_all_of_below/gi)){ 40 | state.hide_all_of_below = true; 41 | return "keyword" 42 | } 43 | 44 | if(stream.match(/^\s*hide/i) && !stream.match(/[^\s]/, false)){ 45 | return "keyword"; 46 | } 47 | 48 | state.groupline = false; 49 | state.hasIP = false; 50 | stream.skipToEnd(); 51 | return "comment"; 52 | } 53 | 54 | if(stream.match(ipv4) || stream.match(ipv6)){ 55 | return "number"; 56 | } 57 | 58 | if(state.groupline){ 59 | if(state.groupid % 2 == 1){ 60 | state.groupline = false; 61 | stream.eatWhile(/[#\s]/); 62 | if(stream.match(/^\s*hide/i) && !stream.match(/[^\s]/, false)){ 63 | return "keyword"; 64 | } 65 | 66 | return "comment"; 67 | }else{ 68 | stream.skipToEnd(); 69 | return "comment"; 70 | } 71 | } 72 | 73 | stream.next(); 74 | 75 | return null; 76 | } 77 | 78 | }; 79 | }); 80 | -------------------------------------------------------------------------------- /core/lib/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tg123/chrome-hostadmin/3cb915992cbae3838704eb9826e6d115342fbc72/core/lib/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /core/lib/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tg123/chrome-hostadmin/3cb915992cbae3838704eb9826e6d115342fbc72/core/lib/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /core/lib/bootstrap/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap.js by @fat & @mdo 3 | * Copyright 2013 Twitter, Inc. 4 | * http://www.apache.org/licenses/LICENSE-2.0.txt 5 | */ 6 | !function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(".dropdown-backdrop").remove(),e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||("ontouchstart"in document.documentElement&&e('