├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── Bug_report.md │ └── Feature_request.md ├── dependabot.yml └── workflows │ ├── alpine.yml │ ├── coverage.yml │ ├── lint-js.yml │ ├── linux.yml │ ├── macos.yml │ └── windows.yml ├── .gitignore ├── .mailmap ├── .nycrc.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── TROUBLESHOOTING.md ├── appveyor.yml ├── bin └── node-sass ├── binding.gyp ├── lib ├── binding.js ├── errors.js ├── extensions.js ├── index.js ├── render.js └── watcher.js ├── media ├── logo.png └── logo.svg ├── memory-tests ├── _measure.js ├── boolean.js ├── function-bridge.js ├── map.js └── string.js ├── package.json ├── scripts ├── build.js ├── install.js ├── prepublish.js └── util │ ├── downloadoptions.js │ ├── proxy.js │ ├── rejectUnauthorized.js │ └── useragent.js ├── src ├── binding.cpp ├── callback_bridge.h ├── create_string.cpp ├── create_string.h ├── custom_function_bridge.cpp ├── custom_function_bridge.h ├── custom_importer_bridge.cpp ├── custom_importer_bridge.h ├── libsass.gyp ├── libsass │ ├── .editorconfig │ ├── .gitattributes │ ├── .github │ │ ├── CONTRIBUTING.md │ │ └── ISSUE_TEMPLATE.md │ ├── .gitignore │ ├── .travis.yml │ ├── COPYING │ ├── GNUmakefile.am │ ├── INSTALL │ ├── LICENSE │ ├── Makefile │ ├── Makefile.conf │ ├── Readme.md │ ├── SECURITY.md │ ├── appveyor.yml │ ├── configure.ac │ ├── contrib │ │ ├── libsass.spec │ │ └── plugin.cpp │ ├── docs │ │ ├── README.md │ │ ├── api-context-example.md │ │ ├── api-context-internal.md │ │ ├── api-context.md │ │ ├── api-doc.md │ │ ├── api-function-example.md │ │ ├── api-function-internal.md │ │ ├── api-function.md │ │ ├── api-importer-example.md │ │ ├── api-importer-internal.md │ │ ├── api-importer.md │ │ ├── api-value-example.md │ │ ├── api-value-internal.md │ │ ├── api-value.md │ │ ├── build-on-darwin.md │ │ ├── build-on-gentoo.md │ │ ├── build-on-windows.md │ │ ├── build-shared-library.md │ │ ├── build-with-autotools.md │ │ ├── build-with-makefiles.md │ │ ├── build-with-mingw.md │ │ ├── build-with-visual-studio.md │ │ ├── build.md │ │ ├── compatibility-plan.md │ │ ├── contributing.md │ │ ├── custom-functions-internal.md │ │ ├── dev-ast-memory.md │ │ ├── implementations.md │ │ ├── plugins.md │ │ ├── setup-environment.md │ │ ├── source-map-internals.md │ │ ├── trace.md │ │ ├── triage.md │ │ └── unicode.md │ ├── extconf.rb │ ├── include │ │ ├── sass.h │ │ ├── sass │ │ │ ├── base.h │ │ │ ├── context.h │ │ │ ├── functions.h │ │ │ ├── values.h │ │ │ ├── version.h │ │ │ └── version.h.in │ │ └── sass2scss.h │ ├── m4 │ │ ├── .gitkeep │ │ └── m4-ax_cxx_compile_stdcxx_11.m4 │ ├── res │ │ └── resource.rc │ ├── script │ │ ├── bootstrap │ │ ├── branding │ │ ├── ci-build-libsass │ │ ├── ci-build-plugin │ │ ├── ci-install-compiler │ │ ├── ci-install-deps │ │ ├── ci-report-coverage │ │ ├── spec │ │ ├── tap-driver │ │ ├── tap-runner │ │ └── test-leaks.pl │ ├── src │ │ ├── GNUmakefile.am │ │ ├── ast.cpp │ │ ├── ast.hpp │ │ ├── ast_def_macros.hpp │ │ ├── ast_fwd_decl.cpp │ │ ├── ast_fwd_decl.hpp │ │ ├── b64 │ │ │ ├── cencode.h │ │ │ └── encode.h │ │ ├── backtrace.cpp │ │ ├── backtrace.hpp │ │ ├── base64vlq.cpp │ │ ├── base64vlq.hpp │ │ ├── bind.cpp │ │ ├── bind.hpp │ │ ├── c99func.c │ │ ├── cencode.c │ │ ├── check_nesting.cpp │ │ ├── check_nesting.hpp │ │ ├── color_maps.cpp │ │ ├── color_maps.hpp │ │ ├── constants.cpp │ │ ├── constants.hpp │ │ ├── context.cpp │ │ ├── context.hpp │ │ ├── cssize.cpp │ │ ├── cssize.hpp │ │ ├── debug.hpp │ │ ├── debugger.hpp │ │ ├── emitter.cpp │ │ ├── emitter.hpp │ │ ├── environment.cpp │ │ ├── environment.hpp │ │ ├── error_handling.cpp │ │ ├── error_handling.hpp │ │ ├── eval.cpp │ │ ├── eval.hpp │ │ ├── expand.cpp │ │ ├── expand.hpp │ │ ├── extend.cpp │ │ ├── extend.hpp │ │ ├── file.cpp │ │ ├── file.hpp │ │ ├── functions.cpp │ │ ├── functions.hpp │ │ ├── inspect.cpp │ │ ├── inspect.hpp │ │ ├── json.cpp │ │ ├── json.hpp │ │ ├── kwd_arg_macros.hpp │ │ ├── lexer.cpp │ │ ├── lexer.hpp │ │ ├── listize.cpp │ │ ├── listize.hpp │ │ ├── mapping.hpp │ │ ├── memory │ │ │ ├── SharedPtr.cpp │ │ │ └── SharedPtr.hpp │ │ ├── node.cpp │ │ ├── node.hpp │ │ ├── operation.hpp │ │ ├── operators.cpp │ │ ├── operators.hpp │ │ ├── output.cpp │ │ ├── output.hpp │ │ ├── parser.cpp │ │ ├── parser.hpp │ │ ├── paths.hpp │ │ ├── plugins.cpp │ │ ├── plugins.hpp │ │ ├── position.cpp │ │ ├── position.hpp │ │ ├── prelexer.cpp │ │ ├── prelexer.hpp │ │ ├── remove_placeholders.cpp │ │ ├── remove_placeholders.hpp │ │ ├── sass.cpp │ │ ├── sass.hpp │ │ ├── sass2scss.cpp │ │ ├── sass_context.cpp │ │ ├── sass_context.hpp │ │ ├── sass_functions.cpp │ │ ├── sass_functions.hpp │ │ ├── sass_util.cpp │ │ ├── sass_util.hpp │ │ ├── sass_values.cpp │ │ ├── sass_values.hpp │ │ ├── source_map.cpp │ │ ├── source_map.hpp │ │ ├── subset_map.cpp │ │ ├── subset_map.hpp │ │ ├── support │ │ │ └── libsass.pc.in │ │ ├── to_c.cpp │ │ ├── to_c.hpp │ │ ├── to_value.cpp │ │ ├── to_value.hpp │ │ ├── units.cpp │ │ ├── units.hpp │ │ ├── utf8.h │ │ ├── utf8 │ │ │ ├── checked.h │ │ │ ├── core.h │ │ │ └── unchecked.h │ │ ├── utf8_string.cpp │ │ ├── utf8_string.hpp │ │ ├── util.cpp │ │ ├── util.hpp │ │ ├── values.cpp │ │ └── values.hpp │ ├── test │ │ ├── test_node.cpp │ │ ├── test_paths.cpp │ │ ├── test_selector_difference.cpp │ │ ├── test_specificity.cpp │ │ ├── test_subset_map.cpp │ │ ├── test_superselector.cpp │ │ └── test_unification.cpp │ ├── version.sh │ └── win │ │ ├── libsass.sln │ │ ├── libsass.sln.DotSettings │ │ ├── libsass.targets │ │ ├── libsass.vcxproj │ │ └── libsass.vcxproj.filters ├── sass_context_wrapper.cpp ├── sass_context_wrapper.h └── sass_types │ ├── boolean.cpp │ ├── boolean.h │ ├── color.cpp │ ├── color.h │ ├── error.cpp │ ├── error.h │ ├── factory.cpp │ ├── factory.h │ ├── list.cpp │ ├── list.h │ ├── map.cpp │ ├── map.h │ ├── null.cpp │ ├── null.h │ ├── number.cpp │ ├── number.h │ ├── sass_value_wrapper.h │ ├── string.cpp │ ├── string.h │ └── value.h └── test ├── api.js ├── binding.js ├── cli.js ├── downloadoptions.js ├── errors.js ├── fixtures ├── compressed │ ├── expected.css │ └── index.scss ├── custom-functions │ ├── setter-expected.css │ ├── setter.scss │ ├── string-conversion-expected.css │ └── string-conversion.scss ├── cwd-include-path │ ├── expected.css │ ├── outside.scss │ └── root │ │ └── index.scss ├── depth-first │ ├── _common.scss │ ├── _struct.scss │ ├── _vars.scss │ ├── a.scss │ ├── a1.scss │ ├── b.scss │ ├── b1.scss │ ├── expected.css │ └── index.scss ├── extras │ ├── my_custom_arrays_of_importers.js │ ├── my_custom_functions_setter.js │ ├── my_custom_functions_string_conversion.js │ ├── my_custom_importer_data.js │ ├── my_custom_importer_data_cb.js │ ├── my_custom_importer_error.js │ ├── my_custom_importer_file.js │ ├── my_custom_importer_file_and_data.js │ ├── my_custom_importer_file_and_data_cb.js │ └── my_custom_importer_file_cb.js ├── follow │ └── foo │ │ └── bar │ │ └── index.scss ├── include-files │ ├── bar.scss │ ├── chained-imports-with-custom-importer.scss │ ├── expected-data-importer.css │ ├── expected-file-importer.css │ ├── expected-importer.css │ ├── file-not-processed-by-loader.scss │ ├── file-processed-by-loader.scss │ ├── foo.scss │ └── index.scss ├── include-path │ ├── expected.css │ ├── functions │ │ └── colorBlue.scss │ ├── index.scss │ └── lib │ │ └── vars.scss ├── indent │ ├── expected.css │ └── index.sass ├── input-directory │ └── sass │ │ ├── _skipped.scss │ │ ├── nested │ │ └── three.scss │ │ ├── one.scss │ │ └── two.scss ├── invalid │ └── index.scss ├── output-directory │ └── index.scss ├── precision │ ├── expected.css │ └── index.scss ├── sass-path │ ├── expected-orange.css │ ├── expected-red.css │ ├── index.scss │ ├── orange │ │ └── colors.scss │ └── red │ │ └── colors.scss ├── simple │ ├── expected.css │ └── index.scss ├── source-comments │ ├── expected.css │ └── index.scss ├── source-map-embed │ ├── expected.css │ └── index.scss ├── source-map │ ├── expected.css │ ├── expected.map │ └── index.scss ├── watcher │ ├── main │ │ ├── one.scss │ │ ├── partials │ │ │ ├── _one.scss │ │ │ ├── _three.scss │ │ │ └── _two.scss │ │ ├── three.scss │ │ └── two.scss │ └── sibling │ │ ├── partials │ │ └── _three.scss │ │ └── three.scss ├── watching-dir-01 │ └── index.scss ├── watching-dir-02 │ ├── foo.scss │ └── index.scss └── watching │ ├── bar.sass │ ├── index.sass │ ├── index.scss │ └── white.scss ├── lowlevel.js ├── runtime.js ├── scripts └── util │ └── proxy.js ├── types.js ├── useragent.js └── watcher.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es6": true, 4 | "node": true 5 | }, 6 | "globals": {}, 7 | "extends": "eslint:recommended", 8 | "overrides": [ 9 | { 10 | "files": [ 11 | "test/**/*.js" 12 | ], 13 | "env": { 14 | "mocha": true 15 | } 16 | } 17 | ], 18 | "rules": { 19 | "no-bitwise": 2, 20 | "curly": 2, 21 | "eqeqeq": 2, 22 | "no-unused-expressions": [ 23 | 2, 24 | { 25 | "allowTernary": true 26 | } 27 | ], 28 | "wrap-iife": [ 29 | 2, 30 | "any" 31 | ], 32 | "indent": [ 33 | 2, 34 | 2, 35 | { 36 | "SwitchCase": 1 37 | } 38 | ], 39 | "linebreak-style": 2, 40 | "no-multi-str": 2, 41 | "new-cap": 2, 42 | "no-caller": 2, 43 | "quotes": [ 44 | 2, 45 | "single" 46 | ], 47 | "semi": 2, 48 | "block-scoped-var": 2 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files we want to always be normalized and converted 5 | # to native line endings on checkout. 6 | 7 | # Declare files that will always have LF line endings on checkout. 8 | *.c text eol=lf 9 | *.css text eol=lf 10 | *.cpp text eol=lf 11 | .editorconfig text eol=lf 12 | .gitattributes text eol=lf 13 | .gitignore text eol=lf 14 | .gitmodules text eol=lf 15 | *.gyp text eol=lf 16 | *.h text eol=lf 17 | *.hpp text eol=lf 18 | *.js text eol=lf 19 | *.json text eol=lf 20 | LICENSE text eol=lf 21 | *.md text eol=lf 22 | node-sass text eol=lf 23 | *.sass text eol=lf 24 | *.scss text eol=lf 25 | *.svg text eol=lf 26 | 27 | # Declare files that will always have CRLF line endings on checkout. 28 | *.bat text eol=crlf 29 | *.cmd text eol=crlf 30 | 31 | # Denote all files that are truly binary and should not be modified. 32 | *.gif binary 33 | *.jpg binary 34 | *.node binary 35 | *.png binary 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: If you're having an issue with installing node-sass or the compiled results 4 | look incorrect 5 | 6 | --- 7 | 8 | 20 | 21 | - NPM version (`npm -v`): 22 | - Node version (`node -v`): 23 | - Node Process (`node -p process.versions`): 24 | - Node Platform (`node -p process.platform`): 25 | - Node architecture (`node -p process.arch`): 26 | - node-sass version (`node -p "require('node-sass').info"`): 27 | - npm node-sass versions (`npm ls node-sass`): 28 | 29 | 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | 18 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" 9 | directory: "/" 10 | open-pull-requests-limit: 99 11 | schedule: 12 | interval: "weekly" 13 | - package-ecosystem: "github-actions" 14 | directory: "/" 15 | open-pull-requests-limit: 99 16 | schedule: 17 | interval: "weekly" 18 | -------------------------------------------------------------------------------- /.github/workflows/alpine.yml: -------------------------------------------------------------------------------- 1 | name: Build bindings for Alpine releases 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - "dependabot/**" 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | container: 13 | image: node:${{ matrix.node }}-alpine 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | node: 18 | - 16 19 | - 18 20 | - 19 21 | - 20 22 | 23 | steps: 24 | - name: Install Alpine build tools 25 | run: apk add --no-cache python3 make git gcc g++ 26 | 27 | - uses: actions/checkout@v4 28 | 29 | - name: Install packages 30 | run: npm install --unsafe-perm 31 | env: 32 | SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: true 33 | 34 | - name: Run tests 35 | run: npm test 36 | 37 | - uses: actions/upload-artifact@v3 38 | if: github.repository_owner == 'sass' && github.event_name != 'pull_request' 39 | with: 40 | name: ${{ matrix.node }} 41 | path: vendor/ 42 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Coverage 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - "dependabot/**" 7 | paths: 8 | - ".nycrc.json" 9 | - "**/*.js" 10 | - "test/**" 11 | - "package.json" 12 | - "bin/node-sass" 13 | - ".github/workflows/coverage.yml" 14 | pull_request: 15 | paths: 16 | - ".nycrc.json" 17 | - "**/*.js" 18 | - "test/**" 19 | - "package.json" 20 | - "bin/node-sass" 21 | - ".github/workflows/coverage.yml" 22 | 23 | jobs: 24 | build: 25 | runs-on: ubuntu-latest 26 | if: github.repository_owner == 'sass' 27 | 28 | steps: 29 | - uses: actions/checkout@v4 30 | 31 | - name: Install packages 32 | run: npm install --unsafe-perm 33 | 34 | - name: Run Coverage 35 | run: npm run coverage 36 | 37 | - name: Coveralls GitHub Action 38 | uses: coverallsapp/github-action@v2 39 | with: 40 | github-token: ${{ secrets.GITHUB_TOKEN }} 41 | -------------------------------------------------------------------------------- /.github/workflows/lint-js.yml: -------------------------------------------------------------------------------- 1 | name: Lint JS 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - "dependabot/**" 7 | paths: 8 | - "**/*.js" 9 | - ".eslintrc.json" 10 | - "package.json" 11 | - "bin/node-sass" 12 | - ".github/workflows/lint-js.yml" 13 | pull_request: 14 | paths: 15 | - "**/*.js" 16 | - ".eslintrc.json" 17 | - "package.json" 18 | - "bin/node-sass" 19 | - ".github/workflows/lint-js.yml" 20 | 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | env: 25 | SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: true 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | 30 | - uses: actions/setup-node@v4 31 | 32 | - name: Install packages 33 | run: npm install --unsafe-perm 34 | 35 | - name: Run Linting 36 | run: npm run lint 37 | -------------------------------------------------------------------------------- /.github/workflows/linux.yml: -------------------------------------------------------------------------------- 1 | name: Build bindings for Linux releases 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - "dependabot/**" 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | runs-on: ${{ matrix.os }} 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | include: 17 | - node: 16 18 | gcc: "gcc-8" 19 | gpp: "g++-8" 20 | os: ubuntu-20.04 21 | - node: 18 22 | gcc: "gcc-8" 23 | gpp: "g++-8" 24 | os: ubuntu-20.04 25 | - node: 19 26 | gcc: "gcc-8" 27 | gpp: "g++-8" 28 | os: ubuntu-20.04 29 | - node: 20 30 | gcc: "gcc-10" 31 | gpp: "g++-10" 32 | os: ubuntu-22.04 33 | 34 | 35 | steps: 36 | - uses: actions/checkout@v4 37 | 38 | - name: Setup Node.js environment 39 | uses: actions/setup-node@v4 40 | with: 41 | node-version: ${{ matrix.node }} 42 | 43 | - name: Setup GCC/G++ 44 | run: sudo apt-get install ${{ matrix.gcc }} ${{ matrix.gpp }} 45 | 46 | - name: Install packages 47 | run: npm install --unsafe-perm 48 | env: 49 | SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: true 50 | CC: ${{ matrix.gcc }} 51 | CXX: ${{ matrix.gpp }} 52 | LINK: ${{ matrix.gcc }} 53 | LINKXX: ${{ matrix.gpp }} 54 | 55 | - name: Run tests 56 | run: npm test 57 | 58 | - uses: actions/upload-artifact@v3 59 | if: github.repository_owner == 'sass' && github.event_name != 'pull_request' 60 | with: 61 | name: ${{ matrix.node }} 62 | path: vendor/ 63 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: Build bindings for macOS releases 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - "dependabot/**" 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | runs-on: macos-latest 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | node: 17 | - 16 18 | - 18 19 | - 19 20 | - 20 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | 25 | - name: Setup Node.js environment 26 | uses: actions/setup-node@v4 27 | with: 28 | node-version: ${{ matrix.node }} 29 | 30 | - name: Install packages 31 | run: npm install --unsafe-perm 32 | env: 33 | SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: true 34 | 35 | - name: Run tests 36 | run: npm test 37 | 38 | - uses: actions/upload-artifact@v3 39 | if: github.repository_owner == 'sass' && github.event_name != 'pull_request' 40 | with: 41 | name: ${{ matrix.node }} 42 | path: vendor/ 43 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Build bindings for Windows releases 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - "dependabot/**" 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | runs-on: windows-2019 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | node: 17 | - 16 18 | - 18 19 | - 19 20 | - 20 21 | 22 | architecture: 23 | - x64 24 | - x86 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | 29 | - name: Setup Node.js environment 30 | uses: actions/setup-node@v4 31 | with: 32 | node-version: ${{ matrix.node }} 33 | architecture: ${{ matrix.architecture }} 34 | 35 | - name: Install packages 36 | run: npm install 37 | env: 38 | SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: true 39 | 40 | - name: Run tests 41 | run: npm test 42 | 43 | - uses: actions/upload-artifact@v3 44 | if: github.repository_owner == 'sass' && github.event_name != 'pull_request' 45 | with: 46 | name: ${{ matrix.node }}-${{ matrix.architecture }} 47 | path: | 48 | vendor/**/binding.node 49 | build/Release/binding.pdb 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | .sass-cache 4 | build 5 | lib-cov 6 | node_modules 7 | vendor 8 | test/html-report 9 | test/lcov-report 10 | test/lcov.info 11 | test/fixtures/watching-css-out-01 12 | test/fixtures/watching-css-out-02 13 | coverage 14 | package-lock.json 15 | .nyc_output 16 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Michał Gołębiowski-Owczarek 2 | -------------------------------------------------------------------------------- /.nycrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "all": true, 3 | "include": [ 4 | "bin/*", 5 | "lib/*.js", 6 | "scripts/**/*.js" 7 | ], 8 | "extension": [ 9 | "node-sass" 10 | ], 11 | "reporter": [ 12 | "lcovonly" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Sass is more than a technology; Sass is driven by the community of individuals 2 | that power its development and use every day. As a community, we want to embrace 3 | the very differences that have made our collaboration so powerful, and work 4 | together to provide the best environment for learning, growing, and sharing of 5 | ideas. It is imperative that we keep Sass a fun, welcoming, challenging, and 6 | fair place to play. 7 | 8 | [The full community guidelines can be found on the Sass website.][link] 9 | 10 | [link]: https://sass-lang.com/community-guidelines 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2016 Andrew Nesbitt 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | - 2 | branches: 3 | only: 4 | - release 5 | - /v\d\.\d\.\d/ 6 | except: 7 | - master 8 | 9 | os: Visual Studio 2017 10 | 11 | configuration: release 12 | 13 | platform: 14 | - x86 15 | 16 | version: "{build}" 17 | 18 | build: off 19 | 20 | clone_folder: c:\projects\node_modules\node-sass 21 | 22 | # http://www.wintellect.com/devcenter/jrobbins/pdb-files-what-every-developer-must-know 23 | # http://help.appveyor.com/discussions/kb/32-how-to-build-on-logical-drive-created-by-subst 24 | init: 25 | - cmd: >- 26 | subst s: c:\projects 27 | - ps: set-location -path s:\node_modules\node-sass 28 | 29 | cache: 30 | - '%userprofile%\.node-gyp' 31 | - '%AppData%\npm-cache' 32 | 33 | environment: 34 | SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: true 35 | matrix: 36 | - nodejs_version: 16 37 | GYP_MSVS_VERSION: 2019 38 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 39 | - nodejs_version: 18 40 | GYP_MSVS_VERSION: 2019 41 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 42 | - nodejs_version: 19 43 | GYP_MSVS_VERSION: 2019 44 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 45 | - nodejs_version: 20 46 | GYP_MSVS_VERSION: 2019 47 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 48 | 49 | 50 | install: 51 | # https://www.appveyor.com/docs/lang/nodejs-iojs/#installing-any-version-of-nodejs-or-iojs 52 | - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) $env:platform 53 | - node --version 54 | - npm --version 55 | - npm install 56 | 57 | test: off 58 | 59 | before_deploy: 60 | # Save artifacts with full qualified names of binding.node and binding.pdb 61 | # (which we use in node-sass-binaries repo) 62 | - ps: >- 63 | Get-ChildItem .\vendor\**\*.node | % { 64 | ( $BindingName = $_.FullName ).Split('\\') | 65 | Select-Object -Last 2 | Select-Object -First 1 } | 66 | .{ process { ( 67 | @( $BindingName, 68 | ( ( $_, "binding.node" ) -join '_' ) ), 69 | @( ".\build\Release\binding.pdb", 70 | ( ( $_, "binding.pdb" ) -join '_' ) ) 71 | ) } } | % { Push-AppveyorArtifact $_[0] -FileName $_[1] } 72 | 73 | deploy: 74 | - provider: GitHub 75 | description: $(APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED) 76 | artifact: 77 | auth_token: 78 | secure: IZIifH990iABY3PQUtkRscTU/NOyYYwptGB6B1y2b618vpphV/2KD/4IWJzSAYAi 79 | on: 80 | appveyor_repo_tag: true # deploy on tag push only 81 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'variables': { 3 | 'libsass_ext%': '', 4 | }, 5 | 'targets': [ 6 | { 7 | 'target_name': 'binding', 8 | 'win_delay_load_hook': 'true', 9 | 'sources': [ 10 | 'src/binding.cpp', 11 | 'src/create_string.cpp', 12 | 'src/custom_function_bridge.cpp', 13 | 'src/custom_importer_bridge.cpp', 14 | 'src/sass_context_wrapper.cpp', 15 | 'src/sass_types/boolean.cpp', 16 | 'src/sass_types/color.cpp', 17 | 'src/sass_types/error.cpp', 18 | 'src/sass_types/factory.cpp', 19 | 'src/sass_types/list.cpp', 20 | 'src/sass_types/map.cpp', 21 | 'src/sass_types/null.cpp', 22 | 'src/sass_types/number.cpp', 23 | 'src/sass_types/string.cpp' 24 | ], 25 | 'msvs_settings': { 26 | 'VCLinkerTool': { 27 | 'SetChecksum': 'true' 28 | } 29 | }, 30 | 'xcode_settings': { 31 | 'CLANG_CXX_LIBRARY': 'libc++', 32 | 'OTHER_LDFLAGS': [], 33 | 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', 34 | 'MACOSX_DEPLOYMENT_TARGET': '10.11' 35 | }, 36 | 'include_dirs': [ 37 | '=16" 20 | }, 21 | "main": "lib/index.js", 22 | "nodeSassConfig": { 23 | "binarySite": "https://github.com/sass/node-sass/releases/download" 24 | }, 25 | "bin": { 26 | "node-sass": "bin/node-sass" 27 | }, 28 | "gypfile": true, 29 | "scripts": { 30 | "coverage": "nyc npm run test", 31 | "install": "node scripts/install.js", 32 | "postinstall": "node scripts/build.js", 33 | "lint": "eslint bin/node-sass lib scripts test", 34 | "test": "mocha test/{*,**/**}.js", 35 | "build": "node scripts/build.js --force", 36 | "prepublishOnly ": "scripts/prepublish.js" 37 | }, 38 | "files": [ 39 | "bin", 40 | "binding.gyp", 41 | "lib", 42 | "scripts", 43 | "src", 44 | "test", 45 | "vendor" 46 | ], 47 | "keywords": [ 48 | "css", 49 | "libsass", 50 | "preprocessor", 51 | "sass", 52 | "scss", 53 | "style" 54 | ], 55 | "dependencies": { 56 | "async-foreach": "^0.1.3", 57 | "chalk": "^4.1.2", 58 | "cross-spawn": "^7.0.3", 59 | "gaze": "^1.0.0", 60 | "get-stdin": "^4.0.1", 61 | "glob": "^7.0.3", 62 | "lodash": "^4.17.15", 63 | "make-fetch-happen": "^10.0.4", 64 | "meow": "^9.0.0", 65 | "nan": "^2.17.0", 66 | "node-gyp": "^10.0.1", 67 | "sass-graph": "^4.0.1", 68 | "stdout-stream": "^1.4.0", 69 | "true-case-path": "^2.2.1" 70 | }, 71 | "devDependencies": { 72 | "eslint": "^8.0.0", 73 | "fs-extra": "^10.0.0", 74 | "mocha": "^9.0.1", 75 | "nyc": "^15.1.0", 76 | "rimraf": "^3.0.2", 77 | "unique-temp-dir": "^1.0.0" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /scripts/prepublish.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * node-sass: scripts/install.js 3 | */ 4 | 5 | var path = require('path'), 6 | rimraf = require('rimraf'); 7 | 8 | function prepublish() { 9 | var vendorPath = path.resolve(__dirname, '..', 'vendor'); 10 | rimraf.sync(vendorPath); 11 | } 12 | 13 | /** 14 | * Run 15 | */ 16 | 17 | prepublish(); 18 | -------------------------------------------------------------------------------- /scripts/util/downloadoptions.js: -------------------------------------------------------------------------------- 1 | var proxy = require('./proxy'), 2 | userAgent = require('./useragent'), 3 | rejectUnauthorized = require('./rejectUnauthorized'); 4 | 5 | /** 6 | * The options passed to make-fetch-happen when downloading the binary 7 | * 8 | * @return {Object} an options object for make-fetch-happen 9 | * @api private 10 | */ 11 | module.exports = function() { 12 | var options = { 13 | strictSSL: rejectUnauthorized(), 14 | timeout: 60000, 15 | headers: { 16 | 'User-Agent': userAgent(), 17 | }, 18 | }; 19 | 20 | var proxyConfig = proxy(); 21 | if (proxyConfig) { 22 | options.proxy = proxyConfig; 23 | } 24 | 25 | return options; 26 | }; 27 | -------------------------------------------------------------------------------- /scripts/util/proxy.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Determine the proxy settings configured by npm 4 | * 5 | * It's possible to configure npm to use a proxy different 6 | * from the system defined proxy. This can be done via the 7 | * `npm config` CLI or the `.npmrc` config file. 8 | * 9 | * If a proxy has been configured in this way we must 10 | * tell request explicitly to use it. 11 | * 12 | * Otherwise we can trust request to the right thing. 13 | * 14 | * @return {String} the proxy configured by npm or an empty string 15 | * @api private 16 | */ 17 | module.exports = function() { 18 | return process.env.npm_config_https_proxy || 19 | process.env.npm_config_proxy || 20 | process.env.npm_config_http_proxy || 21 | ''; 22 | }; 23 | -------------------------------------------------------------------------------- /scripts/util/rejectUnauthorized.js: -------------------------------------------------------------------------------- 1 | var pkg = require('../../package.json'); 2 | 3 | /** 4 | * Get the value of a CLI argument 5 | * 6 | * @param {String} name 7 | * @param {Array} args 8 | * @api private 9 | */ 10 | function getArgument(name, args) { 11 | var flags = args || process.argv.slice(2), 12 | index = flags.lastIndexOf(name); 13 | 14 | if (index === -1 || index + 1 >= flags.length) { 15 | return null; 16 | } 17 | 18 | return flags[index + 1]; 19 | } 20 | 21 | /** 22 | * Get the value of reject-unauthorized 23 | * If environment variable SASS_REJECT_UNAUTHORIZED is non-zero, 24 | * .npmrc variable sass_reject_unauthorized or 25 | * process argument --sass-reject_unauthorized is provided, 26 | * set rejectUnauthorized to true 27 | * Else set to false by default 28 | * 29 | * @return {Boolean} The value of rejectUnauthorized 30 | * @api private 31 | */ 32 | module.exports = function() { 33 | var rejectUnauthorized = false; 34 | 35 | if (getArgument('--sass-reject-unauthorized')) { 36 | rejectUnauthorized = getArgument('--sass-reject-unauthorized'); 37 | } else if (process.env.SASS_REJECT_UNAUTHORIZED !== '0') { 38 | rejectUnauthorized = true; 39 | } else if (process.env.npm_config_sass_reject_unauthorized) { 40 | rejectUnauthorized = process.env.npm_config_sass_reject_unauthorized; 41 | } else if (pkg.nodeSassConfig && pkg.nodeSassConfig.rejectUnauthorized) { 42 | rejectUnauthorized = pkg.nodeSassConfig.rejectUnauthorized; 43 | } 44 | 45 | return rejectUnauthorized; 46 | }; 47 | -------------------------------------------------------------------------------- /scripts/util/useragent.js: -------------------------------------------------------------------------------- 1 | var pkg = require('../../package.json'); 2 | 3 | /** 4 | * A custom user agent use for binary downloads. 5 | * 6 | * @api private 7 | */ 8 | module.exports = function() { 9 | return [ 10 | 'node/', process.version, ' ', 11 | 'node-sass-installer/', pkg.version 12 | ].join(''); 13 | }; 14 | -------------------------------------------------------------------------------- /src/create_string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "create_string.h" 5 | 6 | char* create_string(Nan::MaybeLocal maybevalue) { 7 | v8::Local value; 8 | 9 | if (maybevalue.ToLocal(&value)) { 10 | if (value->IsNull() || !value->IsString()) { 11 | return 0; 12 | } 13 | } else { 14 | return 0; 15 | } 16 | 17 | Nan::Utf8String string(value); 18 | char *str = (char *)malloc(string.length() + 1); 19 | strcpy(str, *string); 20 | return str; 21 | } 22 | -------------------------------------------------------------------------------- /src/create_string.h: -------------------------------------------------------------------------------- 1 | #ifndef CREATE_STRING_H 2 | #define CREATE_STRING_H 3 | 4 | #include 5 | 6 | char* create_string(Nan::MaybeLocal); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/custom_function_bridge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "custom_function_bridge.h" 4 | #include "sass_types/factory.h" 5 | #include "sass_types/value.h" 6 | 7 | Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local _val) const { 8 | SassTypes::Value *value = SassTypes::Factory::unwrap(_val); 9 | if (value) { 10 | return value->get_sass_value(); 11 | } else { 12 | return sass_make_error("A SassValue object was expected."); 13 | } 14 | } 15 | 16 | std::vector> CustomFunctionBridge::pre_process_args(std::vector in) const { 17 | std::vector> argv = std::vector>(); 18 | 19 | for (void* value : in) { 20 | Sass_Value* x = static_cast(value); 21 | SassTypes::Value* y = SassTypes::Factory::create(x); 22 | 23 | argv.push_back(y->get_js_object()); 24 | } 25 | 26 | return argv; 27 | } 28 | -------------------------------------------------------------------------------- /src/custom_function_bridge.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOM_FUNCTION_BRIDGE_H 2 | #define CUSTOM_FUNCTION_BRIDGE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "callback_bridge.h" 8 | 9 | class CustomFunctionBridge : public CallbackBridge { 10 | public: 11 | CustomFunctionBridge(v8::Local cb, bool is_sync) : CallbackBridge(cb, is_sync) {} 12 | 13 | private: 14 | Sass_Value* post_process_return_value(v8::Local) const; 15 | std::vector> pre_process_args(std::vector) const; 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/custom_importer_bridge.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOM_IMPORTER_BRIDGE_H 2 | #define CUSTOM_IMPORTER_BRIDGE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "callback_bridge.h" 8 | 9 | typedef Sass_Import_List SassImportList; 10 | 11 | class CustomImporterBridge : public CallbackBridge { 12 | public: 13 | CustomImporterBridge(v8::Local cb, bool is_sync) : CallbackBridge(cb, is_sync) {} 14 | 15 | private: 16 | SassImportList post_process_return_value(v8::Local) const; 17 | Sass_Import* check_returned_string(Nan::MaybeLocal value, const char *msg) const; 18 | Sass_Import* get_importer_entry(const v8::Local&) const; 19 | std::vector> pre_process_args(std::vector) const; 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/libsass/.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [{Makefile, GNUmakefile.am}] 14 | indent_style = tab 15 | indent_size = 4 16 | -------------------------------------------------------------------------------- /src/libsass/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /src/libsass/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | [todo]: # (Title: Be as meaningful as possible) 2 | [todo]: # (Title: Try to use 60 or less chars) 3 | 4 | [todo]: # (This is only a template!) 5 | [todo]: # (remove unneeded bits) 6 | [todo]: # (use github preview!) 7 | 8 | ## input.scss 9 | 10 | [todo]: # (always test and report with scss syntax) 11 | [todo]: # (use sass only when results differ from scss) 12 | 13 | ```scss 14 | test { 15 | content: bar 16 | } 17 | ``` 18 | 19 | ## Actual results 20 | 21 | [todo]: # (update version info!) 22 | 23 | [libsass 3.X.y][1] 24 | ```css 25 | test { 26 | content: bar; } 27 | ``` 28 | 29 | ## Expected result 30 | 31 | [todo]: # (update version info!) 32 | 33 | ruby sass 3.X.y 34 | ```css 35 | test { 36 | content: bar; } 37 | ``` 38 | 39 | [todo]: # (update version info!) 40 | [todo]: # (example for node-sass!) 41 | 42 | version info: 43 | ```cmd 44 | $ node-sass --version 45 | node-sass 3.X.y (Wrapper) [JavaScript] 46 | libsass 3.X.y (Sass Compiler) [C/C++] 47 | ``` 48 | 49 | [todo]: # (Go to http://libsass.ocbnet.ch/srcmap) 50 | [todo]: # (Enter your SCSS code and hit compile) 51 | [todo]: # (Click `bookmark` and replace the url) 52 | [todo]: # (link is used in actual results above) 53 | 54 | [1]: http://libsass.ocbnet.ch/srcmap/#dGVzdCB7CiAgY29udGVudDogYmFyOyB9Cg== 55 | -------------------------------------------------------------------------------- /src/libsass/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous stuff 2 | 3 | /sassc 4 | /sass-spec 5 | 6 | VERSION 7 | .DS_Store 8 | .sass-cache 9 | *.gem 10 | *.gcno 11 | .svn/* 12 | .cproject 13 | .project 14 | .settings/ 15 | *.db 16 | *.aps 17 | 18 | # Configuration stuff 19 | 20 | GNUmakefile.in 21 | GNUmakefile 22 | /aclocal.m4 23 | /autom4te.cache/ 24 | /src/config.h 25 | /config.h.in 26 | /config.log 27 | /config.status 28 | /configure 29 | /libtool 30 | /m4/libtool.m4 31 | /m4/ltoptions.m4 32 | /m4/ltsugar.m4 33 | /m4/ltversion.m4 34 | /m4/lt~obsolete.m4 35 | /script/ar-lib 36 | /script/compile 37 | /script/config.guess 38 | /script/config.sub 39 | /script/depcomp 40 | /script/install-sh 41 | /script/ltmain.sh 42 | /script/missing 43 | /script/test-driver 44 | /src/stamp-h1 45 | /src/Makefile.in 46 | /src/Makefile 47 | libsass/* 48 | 49 | # Build stuff 50 | 51 | *.o 52 | *.lo 53 | *.so 54 | *.dll 55 | *.a 56 | *.suo 57 | *.sdf 58 | *.opendb 59 | *.opensdf 60 | a.out 61 | libsass.js 62 | tester 63 | tester.exe 64 | build/ 65 | config.h.in* 66 | lib/pkgconfig/ 67 | 68 | bin/* 69 | .deps/ 70 | .libs/ 71 | win/bin 72 | *.user 73 | win/*.db 74 | 75 | # Final results 76 | 77 | sassc++ 78 | libsass.la 79 | src/support/libsass.pc 80 | 81 | # Cloned testing dirs 82 | sassc/ 83 | sass-spec/ 84 | 85 | installer/ 86 | -------------------------------------------------------------------------------- /src/libsass/.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: false 3 | 4 | 5 | # don't create redundant code coverage reports 6 | # - AUTOTOOLS=yes COVERAGE=yes BUILD=static 7 | # - AUTOTOOLS=no COVERAGE=yes BUILD=shared 8 | # - AUTOTOOLS=no COVERAGE=no BUILD=static 9 | 10 | # further speed up day by day travis-ci builds 11 | # re-enable this if you change the makefiles 12 | # this will still catch all coding errors! 13 | # - AUTOTOOLS=yes COVERAGE=no BUILD=static 14 | 15 | # currenty there are various issues when 16 | # built with coverage, clang and autotools 17 | # - AUTOTOOLS=yes COVERAGE=yes BUILD=shared 18 | 19 | matrix: 20 | include : 21 | - os: linux 22 | compiler: gcc 23 | env: AUTOTOOLS=no COVERAGE=yes BUILD=static 24 | - os: linux 25 | compiler: g++-5 26 | env: AUTOTOOLS=yes COVERAGE=no BUILD=shared 27 | addons: 28 | apt: 29 | sources: 30 | - ubuntu-toolchain-r-test 31 | packages: 32 | - g++-5 33 | - os: linux 34 | compiler: clang++-3.7 35 | env: AUTOTOOLS=no COVERAGE=yes BUILD=static 36 | addons: 37 | apt: 38 | sources: 39 | - ubuntu-toolchain-r-test 40 | - llvm-toolchain-precise-3.7 41 | packages: 42 | - clang-3.7 43 | - os: linux 44 | compiler: clang 45 | env: AUTOTOOLS=yes COVERAGE=no BUILD=shared 46 | - os: osx 47 | compiler: clang 48 | env: AUTOTOOLS=no COVERAGE=no BUILD=shared 49 | - os: osx 50 | compiler: clang 51 | env: AUTOTOOLS=no COVERAGE=yes BUILD=static 52 | - os: osx 53 | compiler: clang 54 | env: AUTOTOOLS=yes COVERAGE=no BUILD=shared 55 | 56 | script: 57 | - ./script/ci-build-libsass 58 | - ./script/ci-build-plugin math 59 | - ./script/ci-build-plugin glob 60 | - ./script/ci-build-plugin digest 61 | - ./script/ci-build-plugin tests 62 | before_install: ./script/ci-install-deps 63 | install: ./script/ci-install-compiler 64 | after_success: ./script/ci-report-coverage 65 | -------------------------------------------------------------------------------- /src/libsass/COPYING: -------------------------------------------------------------------------------- 1 | 2 | Copyright (C) 2012 by Hampton Catlin 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8 | of the Software, and to permit persons to whom the Software is furnished to do 9 | so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | 22 | 23 | The following files in the spec were taken from the original Ruby Sass project which 24 | is copyright Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein and under 25 | the same license. 26 | -------------------------------------------------------------------------------- /src/libsass/GNUmakefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 -I script 2 | 3 | AM_COPT = -Wall -O2 4 | AM_COVLDFLAGS = 5 | 6 | if ENABLE_COVERAGE 7 | AM_COPT = -Wall -O1 -fno-omit-frame-pointer --coverage 8 | AM_COVLDFLAGS += -lgcov 9 | endif 10 | 11 | AM_CPPFLAGS = -I$(top_srcdir)/include 12 | AM_CFLAGS = $(AM_COPT) 13 | AM_CXXFLAGS = $(AM_COPT) 14 | AM_LDFLAGS = $(AM_COPT) $(AM_COVLDFLAGS) 15 | 16 | # only needed to support old source tree 17 | # we have moved the files to src folder 18 | AM_CPPFLAGS += -I$(top_srcdir) 19 | 20 | RESOURCES = 21 | if COMPILER_IS_MINGW32 22 | RESOURCES += res/libsass.rc 23 | AM_CXXFLAGS += -std=gnu++0x 24 | else 25 | AM_CXXFLAGS += -std=c++0x 26 | endif 27 | 28 | TEST_EXTENSIONS = .rb 29 | 30 | if ENABLE_TESTS 31 | 32 | SASS_SASSC_PATH ?= $(top_srcdir)/sassc 33 | SASS_SPEC_PATH ?= $(top_srcdir)/sass-spec 34 | 35 | noinst_PROGRAMS = tester 36 | tester_LDADD = src/libsass.la 37 | tester_LDFLAGS = $(AM_LDFLAGS) 38 | nodist_tester_SOURCES = $(SASS_SASSC_PATH)/sassc.c 39 | SASS_SASSC_VERSION ?= `cd "$(SASS_SASSC_PATH)" && ./version.sh` 40 | tester_CFLAGS = $(AM_CFLAGS) -DSASSC_VERSION="\"$(SASS_SASSC_VERSION)\"" 41 | tester_CXXFLAGS = $(AM_CXXFLAGS) -DSASSC_VERSION="\"$(SASS_SASSC_VERSION)\"" 42 | 43 | if ENABLE_COVERAGE 44 | nodist_EXTRA_tester_SOURCES = non-existent-file-to-force-CXX-linking.cxx 45 | endif 46 | 47 | TESTS = $(SASS_SPEC_PATH)/sass-spec.rb 48 | RB_LOG_COMPILER = ./script/tap-runner 49 | AM_RB_LOG_FLAGS = $(RUBY) 50 | 51 | SASS_TEST_FLAGS = -V 3.5 --impl libsass 52 | SASS_TEST_FLAGS += -r $(SASS_SPEC_PATH) 53 | SASS_TEST_FLAGS += -c $(top_srcdir)/tester$(EXEEXT) 54 | AM_TESTS_ENVIRONMENT = TEST_FLAGS='$(SASS_TEST_FLAGS)' 55 | 56 | SASS_TESTER = $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb 57 | 58 | test: 59 | $(SASS_TESTER) $(SASS_TEST_FLAGS) 60 | 61 | test_build: 62 | $(SASS_TESTER) $(SASS_TEST_FLAGS) 63 | 64 | test_full: 65 | $(SASS_TESTER) --run-todo $(SASS_TEST_FLAGS) 66 | 67 | test_probe: 68 | $(SASS_TESTER) --probe-todo $(SASS_TEST_FLAGS) 69 | 70 | .PHONY: test test_build test_full test_probe 71 | 72 | endif 73 | 74 | SUBDIRS = src 75 | -------------------------------------------------------------------------------- /src/libsass/INSTALL: -------------------------------------------------------------------------------- 1 | // Autotools requires us to have this file. Boo. 2 | -------------------------------------------------------------------------------- /src/libsass/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (C) 2012-2016 by the Sass Open Source Foundation 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8 | of the Software, and to permit persons to whom the Software is furnished to do 9 | so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | 22 | 23 | The following files in the spec were taken from the original Ruby Sass project which 24 | is copyright Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein and under 25 | the same license. 26 | -------------------------------------------------------------------------------- /src/libsass/Makefile.conf: -------------------------------------------------------------------------------- 1 | # this is merely a common Makefile multiple implementers can use 2 | # bigger files (in terms of compile time) tend to go to the top, 3 | # so they don't end up as the last compile unit when compiling 4 | # in parallel. But we also want to mix them a little too avoid 5 | # heavy RAM usage peaks. Other than that the order is arbitrary. 6 | 7 | 8 | SOURCES = \ 9 | ast.cpp \ 10 | node.cpp \ 11 | context.cpp \ 12 | constants.cpp \ 13 | functions.cpp \ 14 | color_maps.cpp \ 15 | environment.cpp \ 16 | ast_fwd_decl.cpp \ 17 | bind.cpp \ 18 | file.cpp \ 19 | util.cpp \ 20 | json.cpp \ 21 | units.cpp \ 22 | values.cpp \ 23 | plugins.cpp \ 24 | position.cpp \ 25 | lexer.cpp \ 26 | parser.cpp \ 27 | prelexer.cpp \ 28 | eval.cpp \ 29 | expand.cpp \ 30 | listize.cpp \ 31 | cssize.cpp \ 32 | extend.cpp \ 33 | output.cpp \ 34 | inspect.cpp \ 35 | emitter.cpp \ 36 | check_nesting.cpp \ 37 | remove_placeholders.cpp \ 38 | sass.cpp \ 39 | sass_util.cpp \ 40 | sass_values.cpp \ 41 | sass_context.cpp \ 42 | sass_functions.cpp \ 43 | sass2scss.cpp \ 44 | backtrace.cpp \ 45 | operators.cpp \ 46 | to_c.cpp \ 47 | to_value.cpp \ 48 | source_map.cpp \ 49 | subset_map.cpp \ 50 | error_handling.cpp \ 51 | memory/SharedPtr.cpp \ 52 | utf8_string.cpp \ 53 | base64vlq.cpp 54 | 55 | CSOURCES = cencode.c 56 | -------------------------------------------------------------------------------- /src/libsass/SECURITY.md: -------------------------------------------------------------------------------- 1 | Serious about security 2 | ====================== 3 | 4 | The LibSass team recognizes the important contributions the security research 5 | community can make. We therefore encourage reporting security issues with the 6 | code contained in this repository. 7 | 8 | If you believe you have discovered a security vulnerability, please report it at 9 | https://hackerone.com/libsass instead of GitHub. 10 | 11 | -------------------------------------------------------------------------------- /src/libsass/contrib/libsass.spec: -------------------------------------------------------------------------------- 1 | Name: libsass 2 | Version: %{version} 3 | Release: 1%{?dist} 4 | Summary: A C/C++ implementation of a Sass compiler 5 | 6 | License: MIT 7 | URL: http://libsass.org 8 | Source0: %{name}-%{version}.tar.gz 9 | 10 | BuildRequires: gcc-c++ >= 4.7 11 | BuildRequires: autoconf 12 | BuildRequires: automake 13 | BuildRequires: libtool 14 | 15 | 16 | %description 17 | LibSass is a C/C++ port of the Sass engine. The point is to be simple, fast, and easy to integrate. 18 | 19 | %package devel 20 | Summary: Development files for %{name} 21 | Requires: %{name}%{?_isa} = %{version}-%{release} 22 | 23 | 24 | %description devel 25 | The %{name}-devel package contains libraries and header files for 26 | developing applications that use %{name}. 27 | 28 | 29 | %prep 30 | %setup -q 31 | autoreconf --force --install 32 | 33 | 34 | %build 35 | %configure --disable-static \ 36 | --disable-tests \ 37 | --enable-shared 38 | 39 | make %{?_smp_mflags} 40 | 41 | 42 | %install 43 | %make_install 44 | find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' 45 | 46 | 47 | %post -p /sbin/ldconfig 48 | 49 | %postun -p /sbin/ldconfig 50 | 51 | 52 | %files 53 | %doc Readme.md LICENSE 54 | %{_libdir}/*.so.* 55 | 56 | %files devel 57 | %doc 58 | %{_includedir}/* 59 | %{_libdir}/*.so 60 | %{_libdir}/pkgconfig/*.pc 61 | 62 | 63 | %changelog 64 | * Tue Feb 10 2015 Gawain Lynch - 3.1.0-1 65 | - Initial SPEC file 66 | 67 | -------------------------------------------------------------------------------- /src/libsass/contrib/plugin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // gcc: g++ -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass 7 | // mingw: g++ -shared plugin.cpp -o plugin.dll -Llib -lsass 8 | 9 | extern "C" const char* ADDCALL libsass_get_version() { 10 | return libsass_version(); 11 | } 12 | 13 | union Sass_Value* custom_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp) 14 | { 15 | // get context/option struct associated with this compiler 16 | struct Sass_Context* ctx = sass_compiler_get_context(comp); 17 | struct Sass_Options* opts = sass_compiler_get_options(comp); 18 | // get the cookie from function descriptor 19 | void* cookie = sass_function_get_cookie(cb); 20 | // we actually abuse the void* to store an "int" 21 | return sass_make_number((intptr_t)cookie, "px"); 22 | } 23 | 24 | extern "C" Sass_Function_List ADDCALL libsass_load_functions() 25 | { 26 | // allocate a custom function caller 27 | Sass_Function_Entry c_func = 28 | sass_make_function("foo()", custom_function, (void*)42); 29 | // create list of all custom functions 30 | Sass_Function_List fn_list = sass_make_function_list(1); 31 | // put the only function in this plugin to the list 32 | sass_function_set_list_entry(fn_list, 0, c_func); 33 | // return the list 34 | return fn_list; 35 | } 36 | 37 | Sass_Import_List custom_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) 38 | { 39 | // get the cookie from importer descriptor 40 | void* cookie = sass_importer_get_cookie(cb); 41 | // create a list to hold our import entries 42 | Sass_Import_List incs = sass_make_import_list(1); 43 | // create our only import entry (route path back) 44 | incs[0] = sass_make_import_entry(cur_path, 0, 0); 45 | // return imports 46 | return incs; 47 | } 48 | 49 | extern "C" Sass_Importer_List ADDCALL libsass_load_importers() 50 | { 51 | // allocate a custom function caller 52 | Sass_Importer_Entry c_imp = 53 | sass_make_importer(custom_importer, - 99, (void*)42); 54 | // create list of all custom functions 55 | Sass_Importer_List imp_list = sass_make_importer_list(1); 56 | // put the only function in this plugin to the list 57 | sass_importer_set_list_entry(imp_list, 0, c_imp); 58 | // return the list 59 | return imp_list; 60 | } 61 | -------------------------------------------------------------------------------- /src/libsass/docs/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the LibSass documentation! 2 | 3 | ## First Off 4 | LibSass is just a library. To run the code locally (i.e. to compile your stylesheets), you need an implementer. SassC (get it?) is an implementer written in C. There are a number of other implementations of LibSass - for example Node. We encourage you to write your own port - the whole point of LibSass is that we want to bring Sass to many other languages, not just Ruby! 5 | 6 | We're working hard on moving to full parity with Ruby Sass... learn more at the [The-LibSass-Compatibility-Plan](compatibility-plan.md)! 7 | 8 | ### Implementing LibSass 9 | 10 | If you're interested in implementing LibSass in your own project see the [API Documentation](api-doc.md) which now includes implementing 11 | your own [Sass functions](api-function.md). You may wish to [look at other implementations](implementations.md) for your language of choice. 12 | Or make your own! 13 | 14 | ### Contributing to LibSass 15 | 16 | | Issue Tracker | Issue Triage | Community Guidelines | 17 | |-------------------|----------------------------------|-----------------------------| 18 | | We're always needing help, so check out our issue tracker, help some people out, and read our article on [Contributing](contributing.md)! It's got all the details on what to do! | To help understand the process of triaging bugs, have a look at our [Issue-Triage](triage.md) document. | Oh, and don't forget we always follow [[Sass Community Guidelines|http://sass-lang.com/community-guidelines]]. Be nice and everyone else will be nice too! | 19 | 20 | Please refer to the steps on [Building LibSass](build.md) 21 | -------------------------------------------------------------------------------- /src/libsass/docs/api-context-example.md: -------------------------------------------------------------------------------- 1 | ## Example main.c 2 | 3 | ```C 4 | #include 5 | #include "sass/context.h" 6 | 7 | int main( int argc, const char* argv[] ) 8 | { 9 | 10 | // get the input file from first argument or use default 11 | const char* input = argc > 1 ? argv[1] : "styles.scss"; 12 | 13 | // create the file context and get all related structs 14 | struct Sass_File_Context* file_ctx = sass_make_file_context(input); 15 | struct Sass_Context* ctx = sass_file_context_get_context(file_ctx); 16 | struct Sass_Options* ctx_opt = sass_context_get_options(ctx); 17 | 18 | // configure some options ... 19 | sass_option_set_precision(ctx_opt, 10); 20 | 21 | // context is set up, call the compile step now 22 | int status = sass_compile_file_context(file_ctx); 23 | 24 | // print the result or the error to the stdout 25 | if (status == 0) puts(sass_context_get_output_string(ctx)); 26 | else puts(sass_context_get_error_message(ctx)); 27 | 28 | // release allocated memory 29 | sass_delete_file_context(file_ctx); 30 | 31 | // exit status 32 | return status; 33 | 34 | } 35 | ``` 36 | 37 | ### Compile main.c 38 | 39 | ```bash 40 | gcc -c main.c -o main.o 41 | gcc -o sample main.o -lsass 42 | echo "foo { margin: 21px * 2; }" > foo.scss 43 | ./sample foo.scss => "foo { margin: 42px }" 44 | ``` 45 | 46 | -------------------------------------------------------------------------------- /src/libsass/docs/api-function-example.md: -------------------------------------------------------------------------------- 1 | ## Example main.c 2 | 3 | ```C 4 | #include 5 | #include 6 | #include "sass/context.h" 7 | 8 | union Sass_Value* call_fn_foo(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp) 9 | { 10 | // get context/option struct associated with this compiler 11 | struct Sass_Context* ctx = sass_compiler_get_context(comp); 12 | struct Sass_Options* opts = sass_compiler_get_options(comp); 13 | // get information about previous importer entry from the stack 14 | Sass_Import_Entry import = sass_compiler_get_last_import(comp); 15 | const char* prev_abs_path = sass_import_get_abs_path(import); 16 | const char* prev_imp_path = sass_import_get_imp_path(import); 17 | // get the cookie from function descriptor 18 | void* cookie = sass_function_get_cookie(cb); 19 | // we actually abuse the void* to store an "int" 20 | return sass_make_number((intptr_t)cookie, "px"); 21 | } 22 | 23 | int main( int argc, const char* argv[] ) 24 | { 25 | 26 | // get the input file from first argument or use default 27 | const char* input = argc > 1 ? argv[1] : "styles.scss"; 28 | 29 | // create the file context and get all related structs 30 | struct Sass_File_Context* file_ctx = sass_make_file_context(input); 31 | struct Sass_Context* ctx = sass_file_context_get_context(file_ctx); 32 | struct Sass_Options* ctx_opt = sass_context_get_options(ctx); 33 | 34 | // allocate a custom function caller 35 | Sass_Function_Entry fn_foo = 36 | sass_make_function("foo()", call_fn_foo, (void*)42); 37 | 38 | // create list of all custom functions 39 | Sass_Function_List fn_list = sass_make_function_list(1); 40 | sass_function_set_list_entry(fn_list, 0, fn_foo); 41 | sass_option_set_c_functions(ctx_opt, fn_list); 42 | 43 | // context is set up, call the compile step now 44 | int status = sass_compile_file_context(file_ctx); 45 | 46 | // print the result or the error to the stdout 47 | if (status == 0) puts(sass_context_get_output_string(ctx)); 48 | else puts(sass_context_get_error_message(ctx)); 49 | 50 | // release allocated memory 51 | sass_delete_file_context(file_ctx); 52 | 53 | // exit status 54 | return status; 55 | 56 | } 57 | ``` 58 | 59 | ### Compile main.c 60 | 61 | ```bash 62 | gcc -c main.c -o main.o 63 | gcc -o sample main.o -lsass 64 | echo "foo { margin: foo(); }" > foo.scss 65 | ./sample foo.scss => "foo { margin: 42px }" 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /src/libsass/docs/api-function-internal.md: -------------------------------------------------------------------------------- 1 | ```C 2 | // Struct to hold custom function callback 3 | struct Sass_Function { 4 | const char* signature; 5 | Sass_Function_Fn function; 6 | void* cookie; 7 | }; 8 | ``` 9 | -------------------------------------------------------------------------------- /src/libsass/docs/api-importer-internal.md: -------------------------------------------------------------------------------- 1 | ```C 2 | // External import entry 3 | struct Sass_Import { 4 | char* imp_path; // path as found in the import statement 5 | char *abs_path; // path after importer has resolved it 6 | char* source; 7 | char* srcmap; 8 | // error handling 9 | char* error; 10 | size_t line; 11 | size_t column; 12 | }; 13 | 14 | // Struct to hold importer callback 15 | struct Sass_Importer { 16 | Sass_Importer_Fn importer; 17 | double priority; 18 | void* cookie; 19 | }; 20 | ``` 21 | -------------------------------------------------------------------------------- /src/libsass/docs/api-value-example.md: -------------------------------------------------------------------------------- 1 | ## Example operation.c 2 | 3 | ```C 4 | #include 5 | #include 6 | #include "sass/values.h" 7 | 8 | int main( int argc, const char* argv[] ) 9 | { 10 | 11 | // create two new sass values to be added 12 | union Sass_Value* string = sass_make_string("String"); 13 | union Sass_Value* number = sass_make_number(42, "nits"); 14 | 15 | // invoke the add operation which returns a new sass value 16 | union Sass_Value* total = sass_value_op(ADD, string, number); 17 | 18 | // no further use for the two operands 19 | sass_delete_value(string); 20 | sass_delete_value(number); 21 | 22 | // this works since libsass will always return a 23 | // string for add operations with a string as the 24 | // left hand side. But you should never rely on it! 25 | puts(sass_string_get_value(total)); 26 | 27 | // invoke stringification (uncompressed with precision of 5) 28 | union Sass_Value* result = sass_value_stringify(total, false, 5); 29 | 30 | // no further use for the sum 31 | sass_delete_value(total); 32 | 33 | // print the result - you may want to make 34 | // sure result is indeed a string, altough 35 | // stringify guarantees to return a string 36 | // if (sass_value_is_string(result)) {} 37 | // really depends on your level of paranoia 38 | puts(sass_string_get_value(result)); 39 | 40 | // finally free result 41 | sass_delete_value(result); 42 | 43 | // exit status 44 | return 0; 45 | 46 | } 47 | ``` 48 | 49 | ## Compile operation.c 50 | 51 | ```bash 52 | gcc -c operation.c -o operation.o 53 | gcc -o operation operation.o -lsass 54 | ./operation # => String42nits 55 | ``` 56 | -------------------------------------------------------------------------------- /src/libsass/docs/api-value-internal.md: -------------------------------------------------------------------------------- 1 | ```C 2 | struct Sass_Unknown { 3 | enum Sass_Tag tag; 4 | }; 5 | 6 | struct Sass_Boolean { 7 | enum Sass_Tag tag; 8 | bool value; 9 | }; 10 | 11 | struct Sass_Number { 12 | enum Sass_Tag tag; 13 | double value; 14 | char* unit; 15 | }; 16 | 17 | struct Sass_Color { 18 | enum Sass_Tag tag; 19 | double r; 20 | double g; 21 | double b; 22 | double a; 23 | }; 24 | 25 | struct Sass_String { 26 | enum Sass_Tag tag; 27 | char* value; 28 | }; 29 | 30 | struct Sass_List { 31 | enum Sass_Tag tag; 32 | enum Sass_Separator separator; 33 | size_t length; 34 | // null terminated "array" 35 | union Sass_Value** values; 36 | }; 37 | 38 | struct Sass_Map { 39 | enum Sass_Tag tag; 40 | size_t length; 41 | struct Sass_MapPair* pairs; 42 | }; 43 | 44 | struct Sass_Null { 45 | enum Sass_Tag tag; 46 | }; 47 | 48 | struct Sass_Error { 49 | enum Sass_Tag tag; 50 | char* message; 51 | }; 52 | 53 | struct Sass_Warning { 54 | enum Sass_Tag tag; 55 | char* message; 56 | }; 57 | 58 | union Sass_Value { 59 | struct Sass_Unknown unknown; 60 | struct Sass_Boolean boolean; 61 | struct Sass_Number number; 62 | struct Sass_Color color; 63 | struct Sass_String string; 64 | struct Sass_List list; 65 | struct Sass_Map map; 66 | struct Sass_Null null; 67 | struct Sass_Error error; 68 | struct Sass_Warning warning; 69 | }; 70 | 71 | struct Sass_MapPair { 72 | union Sass_Value* key; 73 | union Sass_Value* value; 74 | }; 75 | ``` 76 | 77 | -------------------------------------------------------------------------------- /src/libsass/docs/build-on-darwin.md: -------------------------------------------------------------------------------- 1 | To install LibSass, make sure the OS X build tools are installed: 2 | 3 | xcode-select --install 4 | 5 | ## Homebrew 6 | 7 | To install homebrew, see [http://brew.sh](http://brew.sh) 8 | 9 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 10 | 11 | You can install the latest version of LibSass quite easily with brew. 12 | 13 | brew install --HEAD libsass 14 | 15 | To update this, do: 16 | 17 | brew reinstall --HEAD libsass 18 | 19 | Brew will build static and shared libraries, and a `libsass.pc` file in `/usr/local/lib/pkgconfig`. 20 | 21 | To use `libsass.pc`, make sure this path is in your `PKG_CONFIG_PATH` 22 | 23 | export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig 24 | 25 | ## Manually 26 | 27 | See the linux instructions [Building-with-autotools](build-with-autotools.md) or [Building-with-makefiles](build-with-makefiles.md) 28 | -------------------------------------------------------------------------------- /src/libsass/docs/build-on-gentoo.md: -------------------------------------------------------------------------------- 1 | Here are two ebuilds to compile LibSass and sassc on gentoo linux. If you do not know how to use these ebuilds, you should probably read the gentoo wiki page about [portage overlays](http://wiki.gentoo.org/wiki/Overlay). 2 | 3 | ## www-misc/libsass/libsass-9999.ebuild 4 | ```ebuild 5 | EAPI=4 6 | 7 | inherit eutils git-2 autotools 8 | 9 | DESCRIPTION="A C/C++ implementation of a Sass compiler." 10 | HOMEPAGE="http://libsass.org/" 11 | EGIT_PROJECT='libsass' 12 | EGIT_REPO_URI="https://github.com/sass/libsass.git" 13 | LICENSE="MIT" 14 | SLOT="0" 15 | KEYWORDS="" 16 | IUSE="" 17 | DEPEND="" 18 | RDEPEND="${DEPEND}" 19 | DEPEND="${DEPEND}" 20 | 21 | pkg_pretend() { 22 | # older gcc is not supported 23 | local major=$(gcc-major-version) 24 | local minor=$(gcc-minor-version) 25 | [[ "${MERGE_TYPE}" != "binary" && ( $major > 4 || ( $major == 4 && $minor < 5 ) ) ]] && \ 26 | die "Sorry, but gcc earlier than 4.5 will not work for LibSass." 27 | } 28 | 29 | src_prepare() { 30 | eautoreconf 31 | } 32 | ``` 33 | 34 | ## www-misc/sassc/sassc-9999.ebuild 35 | ```ebuild 36 | EAPI=4 37 | 38 | inherit eutils git-2 autotools 39 | 40 | DESCRIPTION="Command Line Tool for LibSass." 41 | HOMEPAGE="http://libsass.org/" 42 | EGIT_PROJECT='sassc' 43 | EGIT_REPO_URI="https://github.com/sass/sassc.git" 44 | LICENSE="MIT" 45 | SLOT="0" 46 | KEYWORDS="" 47 | IUSE="" 48 | DEPEND="www-misc/libsass" 49 | RDEPEND="${DEPEND}" 50 | DEPEND="${DEPEND}" 51 | 52 | src_prepare() { 53 | eautoreconf 54 | } 55 | ``` 56 | -------------------------------------------------------------------------------- /src/libsass/docs/build-shared-library.md: -------------------------------------------------------------------------------- 1 | This page is mostly intended for people that want to build a system library that gets distributed via RPMs or other means. This is currently in a experimental phase, as we currently do not really guarantee any ABI forward compatibility. The C API was rewritten to make this possible in the future, but we want to wait some more time till we can call this final and stable. 2 | 3 | Building via autotools 4 | -- 5 | 6 | You want to build a system library only via autotools, since it will create the proper `libtool` files to make it loadable on multiple systems. We hope this works correctly, but nobody of the `libsass` core team has much knowledge in this area. Therefore we are open for comments or improvements by people that have more experience in that matter (like package maintainers from various linux distributions). 7 | 8 | ```bash 9 | apt-get install autoconf libtool 10 | git clone https://github.com/sass/libsass.git 11 | cd libsass 12 | autoreconf --force --install 13 | ./configure \ 14 | --disable-tests \ 15 | --disable-static \ 16 | --enable-shared \ 17 | --prefix=/usr 18 | make -j5 install 19 | cd .. 20 | ``` 21 | 22 | This should install these files 23 | ```bash 24 | # $ ls -la /usr/lib/libsass.* 25 | /usr/lib/libsass.la 26 | /usr/lib/libsass.so -> libsass.so.0.0.9 27 | /usr/lib/libsass.so.0 -> libsass.so.0.0.9 28 | /usr/lib/libsass.so.0.0.9 29 | # $ ls -la /usr/include/sass* 30 | /usr/include/sass.h 31 | /usr/include/sass2scss.h 32 | /usr/include/sass/context.h 33 | /usr/include/sass/functions.h 34 | /usr/include/sass/values.h 35 | ``` 36 | -------------------------------------------------------------------------------- /src/libsass/docs/build-with-autotools.md: -------------------------------------------------------------------------------- 1 | ### Get the sources 2 | ```bash 3 | # using git is preferred 4 | git clone https://github.com/sass/libsass.git 5 | # only needed for sassc and/or testsuite 6 | git clone https://github.com/sass/sassc.git libsass/sassc 7 | git clone https://github.com/sass/sass-spec.git libsass/sass-spec 8 | ``` 9 | 10 | ### Prerequisites 11 | 12 | In order to run autotools you need a few tools installed on your system. 13 | ```bash 14 | yum install automake libtool # RedHat Linux 15 | emerge -a automake libtool # Gentoo Linux 16 | pkgin install automake libtool # SmartOS 17 | ``` 18 | 19 | 20 | ### Create configure script 21 | ```bash 22 | cd libsass 23 | autoreconf --force --install 24 | cd .. 25 | ``` 26 | 27 | ### Create custom makefiles 28 | ```bash 29 | cd libsass 30 | ./configure \ 31 | --disable-tests \ 32 | --disable-shared \ 33 | --prefix=/usr 34 | cd .. 35 | ``` 36 | 37 | ### Build the library 38 | ```bash 39 | make -C libsass -j5 40 | ``` 41 | 42 | ### Install the library 43 | The library will be installed to the location given as `prefix` to `configure`. This is standard behavior for autotools and not `libsass` specific. 44 | ```bash 45 | make -C libsass -j5 install 46 | ``` 47 | 48 | ### Configure options 49 | The `configure` script is created by autotools. To get an overview of available options you can call `./configure --help`. When you execute this script, it will create specific makefiles, which you then use via the regular make command. 50 | 51 | There are some `libsass` specific options: 52 | 53 | ``` 54 | Optional Features: 55 | --enable-tests enable testing the build 56 | --enable-coverage enable coverage report for test suite 57 | --enable-shared build shared libraries [default=yes] 58 | --enable-static build static libraries [default=yes] 59 | 60 | Optional Packages: 61 | --with-sassc-dir= specify directory of sassc sources for 62 | testing (default: sassc) 63 | --with-sass-spec-dir= specify directory of sass-spec for testing 64 | (default: sass-spec) 65 | ``` 66 | 67 | ### Build sassc and run spec test-suite 68 | 69 | ```bash 70 | cd libsass 71 | autoreconf --force --install 72 | ./configure \ 73 | --enable-tests \ 74 | --enable-shared \ 75 | --prefix=/usr 76 | make -j5 test_build 77 | cd .. 78 | ``` 79 | -------------------------------------------------------------------------------- /src/libsass/docs/build-with-makefiles.md: -------------------------------------------------------------------------------- 1 | ### Get the sources 2 | ```bash 3 | # using git is preferred 4 | git clone https://github.com/sass/libsass.git 5 | # only needed for sassc and/or testsuite 6 | git clone https://github.com/sass/sassc.git libsass/sassc 7 | git clone https://github.com/sass/sass-spec.git libsass/sass-spec 8 | ``` 9 | 10 | ### Decide for static or shared library 11 | 12 | `libsass` can be built and linked as a `static` or as a `shared` library. The default is `static`. To change it you can set the `BUILD` environment variable: 13 | 14 | ```bash 15 | export BUILD="shared" 16 | ``` 17 | 18 | Alternatively you can also define it directly when calling make: 19 | 20 | ```bash 21 | BUILD="shared" make ... 22 | ``` 23 | 24 | ### Compile the library 25 | ```bash 26 | make -C libsass -j5 27 | ``` 28 | 29 | ### Results can be found in 30 | ```bash 31 | $ ls libsass/lib 32 | libsass.a libsass.so 33 | ``` 34 | 35 | ### Install onto the system 36 | 37 | We recommend to use [autotools to install](build-with-autotools.md) libsass onto the 38 | system, since that brings all the benefits of using libtools as the main install method. 39 | If you still want to install libsass via the makefile, you need to make sure that gnu 40 | `install` utility (or compatible) is installed on your system. 41 | ```bash 42 | yum install coreutils # RedHat Linux 43 | emerge -a coreutils # Gentoo Linux 44 | pkgin install coreutils # SmartOS 45 | ``` 46 | 47 | You can set the install location by setting `PREFIX` 48 | ```bash 49 | PREFIX="/opt/local" make install 50 | ``` 51 | 52 | 53 | ### Compling sassc 54 | 55 | ```bash 56 | # Let build know library location 57 | export SASS_LIBSASS_PATH="`pwd`/libsass" 58 | # Invokes the sassc makefile 59 | make -C libsass -j5 sassc 60 | ``` 61 | 62 | ### Run the spec test-suite 63 | 64 | ```bash 65 | # needs ruby available 66 | # also gem install minitest 67 | make -C libsass -j5 test_build 68 | ``` 69 | -------------------------------------------------------------------------------- /src/libsass/docs/contributing.md: -------------------------------------------------------------------------------- 1 | First of all, welcome! Thanks for even reading this page. If you're here, you're probably wondering what you can do to help make the LibSass project even more awesome. And, even having that feeling means you are awesome! 2 | 3 | ## I'm a programmer 4 | 5 | Awesome! We need your help. The best thing to do is go find issues that are tagged with both "bug" and "test written". We do spec driven development here and these issues have a test that's written already in the sass-spec project. Go find the test by going to sass-spec/spec/LibSass-todo-issues/issue_XXX/ where XXX is the issue number. Write the code, and compile, and then issue a pull request referencing the issue. We'll quickly verify it and get it merged in! 6 | 7 | To get your dev environment setup, check out our article on [Setup-Dev-Environment](setup-environment.md). 8 | 9 | ## I'm not a backend programmer 10 | 11 | COOL! We also need your help. Doing [Issue-Triage](triage.md) is a big deal and something we need constant help with. That means helping to verify issues, write tests for them, and make sure they are getting fixed. It's being part of the smiling face of the project. 12 | 13 | Also, we need help with the Sass-Spec project itself. Just people to organize, refactor, and understand the tests in there. 14 | 15 | ## I don't know what a computer is? 16 | 17 | Hmm.... well, it's the thing you are looking at right now. Ummm... check out training courses! Then, come back and join us! 18 | -------------------------------------------------------------------------------- /src/libsass/docs/implementations.md: -------------------------------------------------------------------------------- 1 | There are several implementations of `libsass` for a variety of languages. Here are just a few of them. Note, some implementations may or may not be up to date. We have not verified whether they work. 2 | 3 | ### C 4 | * [sassc](https://github.com/hcatlin/sassc) 5 | 6 | ### Crystal 7 | * [sass.cr](https://github.com/straight-shoota/sass.cr) 8 | 9 | ### Elixir 10 | * [sass.ex](https://github.com/scottdavis/sass.ex) 11 | 12 | ### Go 13 | * [go-libsass](https://github.com/wellington/go-libsass) 14 | * [go_sass](https://github.com/suapapa/go_sass) 15 | * [go-sass](https://github.com/SamWhited/go-sass) 16 | 17 | ### Haskell 18 | * [hLibsass](https://github.com/jakubfijalkowski/hlibsass) 19 | * [hSass](https://github.com/jakubfijalkowski/hsass) 20 | 21 | ### Java 22 | * [libsass-maven-plugin](https://github.com/warmuuh/libsass-maven-plugin) 23 | * [jsass](https://github.com/bit3/jsass) 24 | 25 | ### JavaScript 26 | * [sass.js](https://github.com/medialize/sass.js) 27 | 28 | ### Lua 29 | * [lua-sass](https://github.com/craigbarnes/lua-sass) 30 | 31 | ### .NET 32 | * [libsass-net](https://github.com/darrenkopp/libsass-net) 33 | * [NSass](https://github.com/TBAPI-0KA/NSass) 34 | * [Sass.Net](https://github.com/andyalm/Sass.Net) 35 | * [SharpScss](https://github.com/xoofx/SharpScss) 36 | * [LibSassHost](https://github.com/Taritsyn/LibSassHost) 37 | 38 | ### Nim 39 | * [nim-sass](https://github.com/zacharycarter/nim-sass) 40 | 41 | ### node.js 42 | * [node-sass](https://github.com/sass/node-sass) 43 | 44 | ### Perl 45 | * [CSS::Sass](https://github.com/caldwell/CSS-Sass) 46 | * [Text::Sass::XS](https://github.com/ysasaki/Text-Sass-XS) 47 | 48 | ### PHP 49 | * [sassphp](https://github.com/sensational/sassphp) 50 | * [php-sass](https://github.com/lesstif/php-sass) 51 | 52 | ### Python 53 | * [libsass-python](https://github.com/dahlia/libsass-python) 54 | * [SassPython](https://github.com/marianoguerra/SassPython) 55 | * [pylibsass](https://github.com/rsenk330/pylibsass) 56 | * [python-scss](https://github.com/pistolero/python-scss) 57 | 58 | ### Ruby 59 | * [sassruby](https://github.com/hcatlin/sassruby) 60 | 61 | ### Scala 62 | * [Sass-Scala](https://github.com/kkung/Sass-Scala) 63 | 64 | ### Tcl 65 | * [tclsass](https://github.com/flightaware/tclsass) 66 | -------------------------------------------------------------------------------- /src/libsass/docs/plugins.md: -------------------------------------------------------------------------------- 1 | Plugins are shared object files (.so on *nix and .dll on win) that can be loaded by LibSass on runtime. Currently we only provide a way to load internal/custom functions from plugins. In the future we probably will also add a way to provide custom importers via plugins (needs more refactoring to [support multiple importers with some kind of priority system](https://github.com/sass/libsass/issues/962)). 2 | 3 | ## plugin.cpp 4 | 5 | ```C++ 6 | #include 7 | #include 8 | #include 9 | #include "sass_values.h" 10 | 11 | union Sass_Value* ADDCALL call_fn_foo(const union Sass_Value* s_args, void* cookie) 12 | { 13 | // we actually abuse the void* to store an "int" 14 | return sass_make_number((intptr_t)cookie, "px"); 15 | } 16 | 17 | extern "C" const char* ADDCALL libsass_get_version() { 18 | return libsass_version(); 19 | } 20 | 21 | extern "C" Sass_C_Function_List ADDCALL libsass_load_functions() 22 | { 23 | // allocate a custom function caller 24 | Sass_C_Function_Callback fn_foo = 25 | sass_make_function("foo()", call_fn_foo, (void*)42); 26 | // create list of all custom functions 27 | Sass_C_Function_List fn_list = sass_make_function_list(1); 28 | // put the only function in this plugin to the list 29 | sass_function_set_list_entry(fn_list, 0, fn_foo); 30 | // return the list 31 | return fn_list; 32 | } 33 | ``` 34 | 35 | To compile the plugin you need to have LibSass already built as a shared library (to link against it). The commands below expect the shared library in the `lib` sub-directory (`-Llib`). The plugin and the main LibSass process should "consume" the same shared LibSass library on runtime. It will propably also work if they use different LibSass versions. In this case we check if the major versions are compatible (i.e. 3.1.3 and 3.1.1 would be considered compatible). 36 | 37 | ## Compile with gcc on linux 38 | 39 | ```bash 40 | g++ -O2 -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass 41 | ``` 42 | 43 | ## Compile with mingw on windows 44 | 45 | ```bash 46 | g++ -O2 -shared plugin.cpp -o plugin.dll -Llib -lsass 47 | ``` 48 | -------------------------------------------------------------------------------- /src/libsass/docs/setup-environment.md: -------------------------------------------------------------------------------- 1 | ## Requirements 2 | In order to install and setup your local development environment, there are some prerequisites: 3 | 4 | * git 5 | * gcc/clang/llvm (Linux: build tools, Mac OS X: XCode w/ Command Line Tools) 6 | * ruby w/ bundler 7 | 8 | OS X: 9 | First you'll need to install XCode which you can now get from the AppStore installed on your mac. After you download that and run it, then run this on the command line: 10 | 11 | ```` 12 | xcode-select --install 13 | ```` 14 | 15 | ## Cloning the Projects 16 | 17 | First, clone the project and then add a line to your `~/.bash_profile` that will let other programs know where the LibSass dev files are. 18 | 19 | ```` 20 | git clone git@github.com:sass/libsass.git 21 | cd libsass 22 | echo "export SASS_LIBSASS_PATH=$(pwd)" >> ~/.bash_profile 23 | 24 | ```` 25 | 26 | Then, if you run the "bootstrap" script, it should clone all the other required projects. 27 | 28 | ```` 29 | ./script/bootstrap 30 | ```` 31 | 32 | You should now have a `sass-spec` and `sassc` folder within the libsass folder. Both of these are clones of their respective git projects. If you want to do a pull request, remember to work in those folders. For instance, if you want to add a test (see other documentation for how to do that), make sure to commit it to your *fork* of the sass-spec github project. Also, whenever you are running tests, make sure to `pull` from the origin! We want to make sure we are testing against the newest libsass, sassc, and sass-spec! 33 | 34 | Now, try and see if you can build the project. We do that with the `make` command. 35 | 36 | ```` 37 | make 38 | ```` 39 | 40 | At this point, if you get an error, something is most likely wrong with your compiler installation. Yikes. It's hard to cover how to fix this in an article. Feel free to open an issue and we'll try and help! But, remember, before you do that, googling the error message is your friend! Many problems are solved quickly that way. 41 | 42 | ## Running The Spec Against LibSass 43 | 44 | Then, to run the spec against LibSass, just run: 45 | 46 | ```` 47 | ./script/spec 48 | ```` 49 | 50 | If you get an error about `SASS_LIBSASS_PATH`, you may still need to set a variable pointing to the libsass folder, like this: 51 | 52 | ```` 53 | export SASS_LIBSASS_PATH=/Users/you/path/libsass 54 | ```` 55 | 56 | ...where the latter part is to the `libsass` directory you've cloned. You can get this path by typing `pwd` in the Terminal 57 | 58 | ## Running the Spec Against Ruby Sass 59 | 60 | Go into the sass-spec folder that should have been cloned earlier with the "bootstrap" command. Run the following. 61 | 62 | ```` 63 | bundle install 64 | ./sass-spec.rb 65 | ```` 66 | 67 | Voila! Now you are testing against Sass too! 68 | 69 | -------------------------------------------------------------------------------- /src/libsass/docs/source-map-internals.md: -------------------------------------------------------------------------------- 1 | This document is mainly intended for developers! 2 | 3 | # Documenting some of the source map internals 4 | 5 | Since source maps are somewhat a black box to all LibSass maintainers, [I](@mgreter) will try to document my findings with source maps in LibSass, as I come across them. This document will also brievely explain how LibSass parses the source and how it outputs the result. 6 | 7 | The main storage for SourceMap mappings is the `mappings` vector: 8 | 9 | ``` 10 | # in source_map.hpp 11 | vector mappings 12 | # in mappings.hpp 13 | struct Mapping ... 14 | Position original_position; 15 | Position generated_position; 16 | ``` 17 | 18 | ## Every parsed token has its source associated 19 | 20 | LibSass uses a lexical parser. Whenever LibSass finds a token of interest, it creates a specific `AST_Node`, which will hold a reference to the input source with line/column information. `AST_Node` is the base class for all parsed items. They are declared in `ast.hpp` and are used in `parser.hpp`. Here a simple example: 21 | 22 | ``` 23 | if (lex< custom_property_name >()) { 24 | Sass::String* prop = new (ctx.mem) String_Constant(path, source_position, lexed); 25 | return new (ctx.mem) Declaration(path, prop->position(), prop, ...); 26 | } 27 | ``` 28 | 29 | ## How is the `source_position` calculated 30 | 31 | This is automatically done with `lex` in `parser.hpp`. Whenever something is lexed, the `source_position` is updated. But be aware that `source_position` points to the begining of the parsed text. If you need a mapping for the position where the parsing ended, you need to add another call to `lex` (to match nothing)! 32 | 33 | ``` 34 | lex< exactly < empty_str > >(); 35 | end = new (ctx.mem) String_Constant(path, source_position, lexed); 36 | ``` 37 | 38 | ## How are mappings for the output created 39 | 40 | So far we have collected all needed data for all tokens in the input stream. We can now use this information to create mappings when we put things into the output stream. Mappings are created via the `add_mappings` method: 41 | 42 | ``` 43 | # in source_map.hpp 44 | void add_mapping(AST_Node* node); 45 | ``` 46 | 47 | This method is called in two places: 48 | - `Inspect::append_to_buffer` 49 | - `Output_[Nested|Compressed]::append_to_buffer` 50 | 51 | Mappings can only be created for things that have been parsed into a `AST_Node`. Otherwise we do not have the information to create the mappings, which is the reason why LibSass currently only maps the most important tokens in source maps. 52 | -------------------------------------------------------------------------------- /src/libsass/docs/trace.md: -------------------------------------------------------------------------------- 1 | ## This is proposed interface in https://github.com/sass/libsass/pull/1288 2 | 3 | Additional debugging macros with low overhead are available, `TRACE()` and `TRACEINST()`. 4 | 5 | Both macros simulate a string stream, so they can be used like this: 6 | 7 | TRACE() << "Reached."; 8 | 9 | produces: 10 | 11 | [LibSass] parse_value parser.cpp:1384 Reached. 12 | 13 | `TRACE()` 14 | logs function name, source filename, source file name to the standard error and the attached 15 | stream to the standard error. 16 | 17 | `TRACEINST(obj)` 18 | logs object instance address, function name, source filename, source file name to the standard error and the attached stream to the standard error, for example: 19 | 20 | TRACEINST(this) << "String_Constant created " << this; 21 | 22 | produces: 23 | 24 | [LibSass] 0x8031ba980:String_Constant ./ast.hpp:1371 String_Constant created (0,"auto") 25 | 26 | The macros generate output only of `LibSass_TRACE` is set in the environment. 27 | -------------------------------------------------------------------------------- /src/libsass/docs/triage.md: -------------------------------------------------------------------------------- 1 | This is an article about how to help with LibSass issues. Issue triage is a fancy word for explaining how we deal with incoming issues and make sure that the right problems get worked on. The lifecycle of an issue goes like this: 2 | 3 | 1. Issue is reported by a user. 4 | 2. If the issue seems like a bug, then the "bug" tag is added. 5 | 3. If the reporting user didn't also create a spec test over at sass/sass-spec, the "needs test" tag is added. 6 | 4. Verify that Ruby Sass *does not* have the same bug. LibSass strives to be an exact replica of how Ruby Sass works. If it's an issue that neither project has solved, please close the ticket with the "not in sass" label. 7 | 5. The smallest possible breaking test is created in sass-spec. Cut away any extra information or non-breaking code until the core issue is made clear. 8 | 6. Again, verify that the expected output matches the latest Ruby Sass release. Do this by using your own tool OR by running ./sass-spec.rb in the spec folder and making sure that your test passes! 9 | 7. Create the test cases in sass-spec with the name spec/LibSass-todo-issues/issue_XXX/input.scss and expected_output.css where the XXX is the issue number here. 10 | 8. Commit that test to sass-spec, making sure to reference the issue in the comment message like "Test to demonstrate sass/LibSass#XXX". 11 | 9. Once the spec test exists, remove the "needs test" tag and replace it with "test written". 12 | 10. A C++ developer will then work on the issue and issue a pull request to fix the issue. 13 | 11. A core member verifies that the fix does actually fix the spec tests. 14 | 12. The fix is merged into the project. 15 | 13. The spec is moved from the LibSass-todo-issues folder into LibSass-closed-issues 16 | 14. The issue is closed 17 | 15. Have a soda pop or enjoyable beverage of your choice 18 | -------------------------------------------------------------------------------- /src/libsass/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | # .. more stuff 3 | #$LIBPATH.push(Config::CONFIG['libdir']) 4 | $CFLAGS << " #{ENV["CFLAGS"]}" 5 | $LIBS << " #{ENV["LIBS"]}" 6 | create_makefile("libsass") 7 | -------------------------------------------------------------------------------- /src/libsass/include/sass.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_H 2 | #define SASS_H 3 | 4 | // #define DEBUG 1 5 | 6 | // include API headers 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /src/libsass/include/sass/base.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_BASE_H 2 | #define SASS_BASE_H 3 | 4 | // #define DEBUG_SHARED_PTR 5 | 6 | #ifdef _MSC_VER 7 | #pragma warning(disable : 4503) 8 | #ifndef _SCL_SECURE_NO_WARNINGS 9 | #define _SCL_SECURE_NO_WARNINGS 10 | #endif 11 | #ifndef _CRT_SECURE_NO_WARNINGS 12 | #define _CRT_SECURE_NO_WARNINGS 13 | #endif 14 | #ifndef _CRT_NONSTDC_NO_DEPRECATE 15 | #define _CRT_NONSTDC_NO_DEPRECATE 16 | #endif 17 | #endif 18 | 19 | #include 20 | #include 21 | 22 | #ifdef __GNUC__ 23 | #define DEPRECATED(func) func __attribute__ ((deprecated)) 24 | #elif defined(_MSC_VER) 25 | #define DEPRECATED(func) __declspec(deprecated) func 26 | #else 27 | #pragma message("WARNING: You need to implement DEPRECATED for this compiler") 28 | #define DEPRECATED(func) func 29 | #endif 30 | 31 | #ifdef _WIN32 32 | 33 | /* You should define ADD_EXPORTS *only* when building the DLL. */ 34 | #ifdef ADD_EXPORTS 35 | #define ADDAPI __declspec(dllexport) 36 | #define ADDCALL __cdecl 37 | #else 38 | #define ADDAPI 39 | #define ADDCALL 40 | #endif 41 | 42 | #else /* _WIN32 not defined. */ 43 | 44 | /* Define with no value on non-Windows OSes. */ 45 | #define ADDAPI 46 | #define ADDCALL 47 | 48 | #endif 49 | 50 | /* Make sure functions are exported with C linkage under C++ compilers. */ 51 | #ifdef __cplusplus 52 | extern "C" { 53 | #endif 54 | 55 | 56 | // Different render styles 57 | enum Sass_Output_Style { 58 | SASS_STYLE_NESTED, 59 | SASS_STYLE_EXPANDED, 60 | SASS_STYLE_COMPACT, 61 | SASS_STYLE_COMPRESSED, 62 | // only used internaly 63 | SASS_STYLE_INSPECT, 64 | SASS_STYLE_TO_SASS 65 | }; 66 | 67 | // to allocate buffer to be filled 68 | ADDAPI void* ADDCALL sass_alloc_memory(size_t size); 69 | // to allocate a buffer from existing string 70 | ADDAPI char* ADDCALL sass_copy_c_string(const char* str); 71 | // to free overtaken memory when done 72 | ADDAPI void ADDCALL sass_free_memory(void* ptr); 73 | 74 | // Some convenient string helper function 75 | ADDAPI char* ADDCALL sass_string_quote (const char* str, const char quote_mark); 76 | ADDAPI char* ADDCALL sass_string_unquote (const char* str); 77 | 78 | // Implemented sass language version 79 | // Hardcoded version 3.4 for time being 80 | ADDAPI const char* ADDCALL libsass_version(void); 81 | 82 | // Get compiled libsass language 83 | ADDAPI const char* ADDCALL libsass_language_version(void); 84 | 85 | #ifdef __cplusplus 86 | } // __cplusplus defined. 87 | #endif 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/libsass/include/sass/version.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_VERSION_H 2 | #define SASS_VERSION_H 3 | 4 | #ifndef LIBSASS_VERSION 5 | #define LIBSASS_VERSION "[NA]" 6 | #endif 7 | 8 | #ifndef LIBSASS_LANGUAGE_VERSION 9 | #define LIBSASS_LANGUAGE_VERSION "3.5" 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/libsass/include/sass/version.h.in: -------------------------------------------------------------------------------- 1 | #ifndef SASS_VERSION_H 2 | #define SASS_VERSION_H 3 | 4 | #ifndef LIBSASS_VERSION 5 | #define LIBSASS_VERSION "@PACKAGE_VERSION@" 6 | #endif 7 | 8 | #ifndef LIBSASS_LANGUAGE_VERSION 9 | #define LIBSASS_LANGUAGE_VERSION "3.5" 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/libsass/m4/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sass/node-sass/107ded9434cfca43dbd9dfbaeb5c349228bf5cee/src/libsass/m4/.gitkeep -------------------------------------------------------------------------------- /src/libsass/res/resource.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 1,0,0,0 6 | PRODUCTVERSION 1,0,0,0 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | #ifdef _DEBUG 9 | FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE 10 | #else 11 | FILEFLAGS 0 12 | #endif 13 | FILEOS VOS_NT_WINDOWS32 14 | FILETYPE VFT_DLL 15 | FILESUBTYPE VFT2_UNKNOWN 16 | BEGIN 17 | BLOCK "StringFileInfo" 18 | BEGIN 19 | BLOCK "080904b0" 20 | BEGIN 21 | VALUE "CompanyName", "Sass Open Source Foundation" 22 | VALUE "FileDescription", "A C/C++ implementation of a Sass compiler" 23 | VALUE "FileVersion", "1.0.0.0" 24 | VALUE "InternalName", "libsass" 25 | VALUE "LegalCopyright", "\251 2017 libsass.org" 26 | VALUE "OriginalFilename", "libsass.dll" 27 | VALUE "ProductName", "LibSass Library" 28 | VALUE "ProductVersion", "1.0.0.0" 29 | END 30 | END 31 | BLOCK "VarFileInfo" 32 | BEGIN 33 | VALUE "Translation", 0x809, 1200 34 | END 35 | END 36 | -------------------------------------------------------------------------------- /src/libsass/script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | script/branding 4 | 5 | : ${SASS_SPEC_PATH:="sass-spec"} 6 | : ${SASS_SASSC_PATH:="sassc" } 7 | 8 | if [ ! -d $SASS_SPEC_PATH ]; then 9 | git clone https://github.com/sass/sass-spec.git $SASS_SPEC_PATH 10 | fi 11 | if [ ! -d $SASS_SASSC_PATH ]; then 12 | git clone https://github.com/sass/sassc.git $SASS_SASSC_PATH 13 | fi 14 | -------------------------------------------------------------------------------- /src/libsass/script/branding: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo " " 4 | echo " _ ___ ____ ____ _ ____ ____ " 5 | echo "| | |_ _| __ ) ___| / \ / ___/ ___| " 6 | echo "| | | || _ \___ \ / _ \ \___ \___ \ " 7 | echo "| |___ | || |_) |__) / ___ \ ___) |__) |" 8 | echo "|_____|___|____/____/_/ \_\____/____/ " 9 | echo " " 10 | 11 | -------------------------------------------------------------------------------- /src/libsass/script/ci-build-plugin: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PLUGIN=$1 4 | RUBY_BIN=ruby 5 | SASS_SPEC_PATH=sass-spec 6 | SASSC_BIN=sassc/bin/sassc 7 | SASS_SPEC_SPEC_DIR=plugins/libsass-${PLUGIN}/test 8 | 9 | if [ -e ./tester ] ; then 10 | SASSC_BIN=./tester 11 | fi 12 | 13 | if [ -d ./build/lib ] ; then 14 | cp -a build/lib lib 15 | fi 16 | 17 | if [ "x$1" == "x" ] ; then 18 | echo "No plugin name given" 19 | exit 1 20 | fi 21 | 22 | if [ "x$COVERAGE" == "0" ] ; then 23 | unset COVERAGE 24 | fi 25 | 26 | export EXTRA_CFLAGS="" 27 | export EXTRA_CXXFLAGS="" 28 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 29 | # osx doesn't seem to know gcov lib? 30 | export EXTRA_LDFLAGS="--coverage" 31 | else 32 | export EXTRA_LDFLAGS="-lgcov --coverage" 33 | fi 34 | 35 | mkdir -p plugins 36 | if [ ! -d plugins/libsass-${PLUGIN} ] ; then 37 | git clone https://github.com/mgreter/libsass-${PLUGIN} plugins/libsass-${PLUGIN} 38 | fi 39 | if [ ! -d plugins/libsass-${PLUGIN}/build ] ; then 40 | mkdir plugins/libsass-${PLUGIN}/build 41 | fi 42 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 43 | 44 | cd plugins/libsass-${PLUGIN}/build 45 | cmake -G "Unix Makefiles" -D LIBSASS_DIR="../../.." .. 46 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 47 | make VERBOSE=1 -j2 48 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 49 | cd ../../.. 50 | 51 | # glob only works on paths relative to imports 52 | if [ "x$PLUGIN" == "xglob" ]; then 53 | ${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build ${SASS_SPEC_SPEC_DIR}/basic/input.scss > ${SASS_SPEC_SPEC_DIR}/basic/result.css 54 | ${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build ${SASS_SPEC_SPEC_DIR}/basic/input.scss --sourcemap > /dev/null 55 | else 56 | cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --precision 5 --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic > ${SASS_SPEC_SPEC_DIR}/basic/result.css 57 | cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --precision 5 --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic --sourcemap > /dev/null 58 | fi 59 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 60 | 61 | diff ${SASS_SPEC_SPEC_DIR}/basic/expected_output.css ${SASS_SPEC_SPEC_DIR}/basic/result.css 62 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 63 | -------------------------------------------------------------------------------- /src/libsass/script/ci-install-compiler: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | gem install minitest 4 | gem install minitap 5 | 6 | pip2 install --user 'requests[security]' 7 | -------------------------------------------------------------------------------- /src/libsass/script/ci-install-deps: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ "x$COVERAGE" == "xyes" ]; then 3 | pip2 install --user gcovr 4 | pip2 install --user cpp-coveralls 5 | else 6 | echo "no dependencies to install" 7 | fi 8 | 9 | if [ "x$AUTOTOOLS" == "xyes" ]; then 10 | AUTOTOOLS=yes 11 | 12 | if [ "$TRAVIS_OS_NAME" == "linux" ]; then 13 | sudo add-apt-repository -y ppa:rbose-debianizer/automake &> /dev/null 14 | sudo apt-get -qq update 15 | sudo apt-get -qq install automake 16 | fi 17 | 18 | fi 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /src/libsass/script/ci-report-coverage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "x$COVERAGE" = "xyes" ]; then 4 | 5 | # find / -name "gcovr" 6 | # find / -name "coveralls" 7 | # this is only needed for mac os x builds! 8 | PATH=$PATH:/Users/travis/Library/Python/2.7/bin/ 9 | 10 | 11 | # exclude some directories from profiling (.libs is from autotools) 12 | export EXCLUDE_COVERAGE="--exclude plugins 13 | --exclude sassc/sassc.c 14 | --exclude src/sass-spec 15 | --exclude src/.libs 16 | --exclude src/debug.hpp 17 | --exclude src/json.cpp 18 | --exclude src/json.hpp 19 | --exclude src/cencode.c 20 | --exclude src/b64 21 | --exclude src/utf8 22 | --exclude src/utf8_string.hpp 23 | --exclude src/utf8.h 24 | --exclude src/utf8_string.cpp 25 | --exclude src/sass2scss.h 26 | --exclude src/sass2scss.cpp 27 | --exclude src/test 28 | --exclude src/posix 29 | --exclude src/debugger.hpp" 30 | # debug used gcov version 31 | # option not available on mac 32 | if [ "$TRAVIS_OS_NAME" != "osx" ]; then 33 | gcov -v 34 | fi 35 | # create summarized report 36 | gcovr -r . 37 | # submit report to coveralls.io 38 | coveralls $EXCLUDE_COVERAGE --gcov-options '\-lp' 39 | 40 | else 41 | echo "skip coverage reporting" 42 | fi 43 | -------------------------------------------------------------------------------- /src/libsass/script/spec: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | script/bootstrap 4 | 5 | make $MAKE_OPTS test_build 6 | -------------------------------------------------------------------------------- /src/libsass/script/tap-runner: -------------------------------------------------------------------------------- 1 | $@ $TEST_FLAGS --tap --silent | tapout tap 2 | -------------------------------------------------------------------------------- /src/libsass/src/GNUmakefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 -I script 2 | 3 | AM_COPT = -Wall -O2 4 | AM_COVLDFLAGS = 5 | 6 | if ENABLE_COVERAGE 7 | AM_COPT = -O0 --coverage 8 | AM_COVLDFLAGS += -lgcov 9 | endif 10 | 11 | AM_CPPFLAGS = -I$(top_srcdir)/include 12 | AM_CFLAGS = $(AM_COPT) 13 | AM_CXXFLAGS = $(AM_COPT) 14 | AM_LDFLAGS = $(AM_COPT) $(AM_COVLDFLAGS) 15 | 16 | if COMPILER_IS_MINGW32 17 | AM_CXXFLAGS += -std=gnu++0x 18 | else 19 | AM_CXXFLAGS += -std=c++0x 20 | endif 21 | 22 | EXTRA_DIST = \ 23 | COPYING \ 24 | INSTALL \ 25 | LICENSE \ 26 | Readme.md 27 | 28 | pkgconfigdir = $(libdir)/pkgconfig 29 | pkgconfig_DATA = support/libsass.pc 30 | 31 | lib_LTLIBRARIES = libsass.la 32 | 33 | include $(top_srcdir)/Makefile.conf 34 | 35 | libsass_la_SOURCES = ${CSOURCES} ${SOURCES} 36 | 37 | libsass_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 1:0:0 38 | 39 | if ENABLE_TESTS 40 | if ENABLE_COVERAGE 41 | nodist_EXTRA_libsass_la_SOURCES = non-existent-file-to-force-CXX-linking.cxx 42 | endif 43 | endif 44 | 45 | include_HEADERS = $(top_srcdir)/include/sass.h \ 46 | $(top_srcdir)/include/sass2scss.h 47 | 48 | sass_includedir = $(includedir)/sass 49 | 50 | sass_include_HEADERS = $(top_srcdir)/include/sass/base.h \ 51 | $(top_srcdir)/include/sass/values.h \ 52 | $(top_srcdir)/include/sass/version.h \ 53 | $(top_srcdir)/include/sass/context.h \ 54 | $(top_srcdir)/include/sass/functions.h 55 | -------------------------------------------------------------------------------- /src/libsass/src/ast_def_macros.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_AST_DEF_MACROS_H 2 | #define SASS_AST_DEF_MACROS_H 3 | 4 | // Helper class to switch a flag and revert once we go out of scope 5 | template 6 | class LocalOption { 7 | private: 8 | T* var; // pointer to original variable 9 | T orig; // copy of the original option 10 | public: 11 | LocalOption(T& var) 12 | { 13 | this->var = &var; 14 | this->orig = var; 15 | } 16 | LocalOption(T& var, T orig) 17 | { 18 | this->var = &var; 19 | this->orig = var; 20 | *(this->var) = orig; 21 | } 22 | void reset() 23 | { 24 | *(this->var) = this->orig; 25 | } 26 | ~LocalOption() { 27 | *(this->var) = this->orig; 28 | } 29 | }; 30 | 31 | #define LOCAL_FLAG(name,opt) LocalOption flag_##name(name, opt) 32 | #define LOCAL_COUNT(name,opt) LocalOption cnt_##name(name, opt) 33 | 34 | #define NESTING_GUARD(name) \ 35 | LocalOption cnt_##name(name, name + 1); \ 36 | if (name > MAX_NESTING) throw Exception::NestingLimitError(pstate, traces); \ 37 | 38 | #define ATTACH_OPERATIONS()\ 39 | virtual void perform(Operation* op) { (*op)(this); }\ 40 | virtual AST_Node_Ptr perform(Operation* op) { return (*op)(this); }\ 41 | virtual Statement_Ptr perform(Operation* op) { return (*op)(this); }\ 42 | virtual Expression_Ptr perform(Operation* op) { return (*op)(this); }\ 43 | virtual Selector_Ptr perform(Operation* op) { return (*op)(this); }\ 44 | virtual std::string perform(Operation* op) { return (*op)(this); }\ 45 | virtual union Sass_Value* perform(Operation* op) { return (*op)(this); }\ 46 | virtual Value_Ptr perform(Operation* op) { return (*op)(this); } 47 | 48 | #define ADD_PROPERTY(type, name)\ 49 | protected:\ 50 | type name##_;\ 51 | public:\ 52 | type name() const { return name##_; }\ 53 | type name(type name##__) { return name##_ = name##__; }\ 54 | private: 55 | 56 | #define HASH_PROPERTY(type, name)\ 57 | protected:\ 58 | type name##_;\ 59 | public:\ 60 | type name() const { return name##_; }\ 61 | type name(type name##__) { hash_ = 0; return name##_ = name##__; }\ 62 | private: 63 | 64 | #define ADD_CONSTREF(type, name) \ 65 | protected: \ 66 | type name##_; \ 67 | public: \ 68 | const type& name() const { return name##_; } \ 69 | void name(type name##__) { name##_ = name##__; } \ 70 | private: 71 | 72 | #define HASH_CONSTREF(type, name) \ 73 | protected: \ 74 | type name##_; \ 75 | public: \ 76 | const type& name() const { return name##_; } \ 77 | void name(type name##__) { hash_ = 0; name##_ = name##__; } \ 78 | private: 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/libsass/src/ast_fwd_decl.cpp: -------------------------------------------------------------------------------- 1 | #include "ast.hpp" 2 | 3 | namespace Sass { 4 | 5 | #define IMPLEMENT_BASE_CAST(T) \ 6 | template<> \ 7 | T* Cast(AST_Node* ptr) { \ 8 | return dynamic_cast(ptr); \ 9 | }; \ 10 | \ 11 | template<> \ 12 | const T* Cast(const AST_Node* ptr) { \ 13 | return dynamic_cast(ptr); \ 14 | }; \ 15 | 16 | IMPLEMENT_BASE_CAST(AST_Node) 17 | IMPLEMENT_BASE_CAST(Expression) 18 | IMPLEMENT_BASE_CAST(Statement) 19 | IMPLEMENT_BASE_CAST(Has_Block) 20 | IMPLEMENT_BASE_CAST(PreValue) 21 | IMPLEMENT_BASE_CAST(Value) 22 | IMPLEMENT_BASE_CAST(List) 23 | IMPLEMENT_BASE_CAST(String) 24 | IMPLEMENT_BASE_CAST(String_Constant) 25 | IMPLEMENT_BASE_CAST(Supports_Condition) 26 | IMPLEMENT_BASE_CAST(Selector) 27 | IMPLEMENT_BASE_CAST(Simple_Selector) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/libsass/src/b64/cencode.h: -------------------------------------------------------------------------------- 1 | /* 2 | cencode.h - c header for a base64 encoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CENCODE_H 9 | #define BASE64_CENCODE_H 10 | 11 | typedef enum 12 | { 13 | step_A, step_B, step_C 14 | } base64_encodestep; 15 | 16 | typedef struct 17 | { 18 | base64_encodestep step; 19 | char result; 20 | int stepcount; 21 | } base64_encodestate; 22 | 23 | void base64_init_encodestate(base64_encodestate* state_in); 24 | 25 | char base64_encode_value(char value_in); 26 | 27 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); 28 | 29 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in); 30 | 31 | #endif /* BASE64_CENCODE_H */ 32 | 33 | -------------------------------------------------------------------------------- /src/libsass/src/b64/encode.h: -------------------------------------------------------------------------------- 1 | // :mode=c++: 2 | /* 3 | encode.h - c++ wrapper for a base64 encoding algorithm 4 | 5 | This is part of the libb64 project, and has been placed in the public domain. 6 | For details, see http://sourceforge.net/projects/libb64 7 | */ 8 | #ifndef BASE64_ENCODE_H 9 | #define BASE64_ENCODE_H 10 | 11 | #include 12 | 13 | namespace base64 14 | { 15 | extern "C" 16 | { 17 | #include "cencode.h" 18 | } 19 | 20 | struct encoder 21 | { 22 | base64_encodestate _state; 23 | int _buffersize; 24 | 25 | encoder(int buffersize_in = BUFFERSIZE) 26 | : _buffersize(buffersize_in) 27 | { 28 | base64_init_encodestate(&_state); 29 | } 30 | 31 | int encode(char value_in) 32 | { 33 | return base64_encode_value(value_in); 34 | } 35 | 36 | int encode(const char* code_in, const int length_in, char* plaintext_out) 37 | { 38 | return base64_encode_block(code_in, length_in, plaintext_out, &_state); 39 | } 40 | 41 | int encode_end(char* plaintext_out) 42 | { 43 | return base64_encode_blockend(plaintext_out, &_state); 44 | } 45 | 46 | void encode(std::istream& istream_in, std::ostream& ostream_in) 47 | { 48 | base64_init_encodestate(&_state); 49 | // 50 | const int N = _buffersize; 51 | char* plaintext = new char[N]; 52 | char* code = new char[2*N]; 53 | int plainlength; 54 | int codelength; 55 | 56 | do 57 | { 58 | istream_in.read(plaintext, N); 59 | plainlength = static_cast(istream_in.gcount()); 60 | // 61 | codelength = encode(plaintext, plainlength, code); 62 | ostream_in.write(code, codelength); 63 | } 64 | while (istream_in.good() && plainlength > 0); 65 | 66 | codelength = encode_end(code); 67 | ostream_in.write(code, codelength); 68 | // 69 | base64_init_encodestate(&_state); 70 | 71 | delete [] code; 72 | delete [] plaintext; 73 | } 74 | }; 75 | 76 | } // namespace base64 77 | 78 | #endif // BASE64_ENCODE_H 79 | 80 | -------------------------------------------------------------------------------- /src/libsass/src/backtrace.cpp: -------------------------------------------------------------------------------- 1 | #include "backtrace.hpp" 2 | 3 | namespace Sass { 4 | 5 | const std::string traces_to_string(Backtraces traces, std::string indent) { 6 | 7 | std::stringstream ss; 8 | std::string cwd(File::get_cwd()); 9 | 10 | bool first = true; 11 | size_t i_beg = traces.size() - 1; 12 | size_t i_end = std::string::npos; 13 | for (size_t i = i_beg; i != i_end; i --) { 14 | 15 | const Backtrace& trace = traces[i]; 16 | 17 | // make path relative to the current directory 18 | std::string rel_path(File::abs2rel(trace.pstate.path, cwd, cwd)); 19 | 20 | // skip functions on error cases (unsure why ruby sass does this) 21 | // if (trace.caller.substr(0, 6) == ", in f") continue; 22 | 23 | if (first) { 24 | ss << indent; 25 | ss << "on line "; 26 | ss << trace.pstate.line + 1; 27 | ss << " of " << rel_path; 28 | // ss << trace.caller; 29 | first = false; 30 | } else { 31 | ss << trace.caller; 32 | ss << std::endl; 33 | ss << indent; 34 | ss << "from line "; 35 | ss << trace.pstate.line + 1; 36 | ss << " of " << rel_path; 37 | } 38 | 39 | } 40 | 41 | ss << std::endl; 42 | return ss.str(); 43 | 44 | } 45 | 46 | }; 47 | -------------------------------------------------------------------------------- /src/libsass/src/backtrace.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_BACKTRACE_H 2 | #define SASS_BACKTRACE_H 3 | 4 | #include 5 | #include 6 | #include "file.hpp" 7 | #include "position.hpp" 8 | 9 | namespace Sass { 10 | 11 | struct Backtrace { 12 | 13 | ParserState pstate; 14 | std::string caller; 15 | 16 | Backtrace(ParserState pstate, std::string c = "") 17 | : pstate(pstate), 18 | caller(c) 19 | { } 20 | 21 | }; 22 | 23 | typedef std::vector Backtraces; 24 | 25 | const std::string traces_to_string(Backtraces traces, std::string indent = "\t"); 26 | 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/libsass/src/base64vlq.cpp: -------------------------------------------------------------------------------- 1 | #include "sass.hpp" 2 | #include "base64vlq.hpp" 3 | 4 | namespace Sass { 5 | 6 | std::string Base64VLQ::encode(const int number) const 7 | { 8 | std::string encoded = ""; 9 | 10 | int vlq = to_vlq_signed(number); 11 | 12 | do { 13 | int digit = vlq & VLQ_BASE_MASK; 14 | vlq >>= VLQ_BASE_SHIFT; 15 | if (vlq > 0) { 16 | digit |= VLQ_CONTINUATION_BIT; 17 | } 18 | encoded += base64_encode(digit); 19 | } while (vlq > 0); 20 | 21 | return encoded; 22 | } 23 | 24 | char Base64VLQ::base64_encode(const int number) const 25 | { 26 | int index = number; 27 | if (index < 0) index = 0; 28 | if (index > 63) index = 63; 29 | return CHARACTERS[index]; 30 | } 31 | 32 | int Base64VLQ::to_vlq_signed(const int number) const 33 | { 34 | return (number < 0) ? ((-number) << 1) + 1 : (number << 1) + 0; 35 | } 36 | 37 | const char* Base64VLQ::CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 38 | 39 | const int Base64VLQ::VLQ_BASE_SHIFT = 5; 40 | const int Base64VLQ::VLQ_BASE = 1 << VLQ_BASE_SHIFT; 41 | const int Base64VLQ::VLQ_BASE_MASK = VLQ_BASE - 1; 42 | const int Base64VLQ::VLQ_CONTINUATION_BIT = VLQ_BASE; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/libsass/src/base64vlq.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_BASE64VLQ_H 2 | #define SASS_BASE64VLQ_H 3 | 4 | #include 5 | 6 | namespace Sass { 7 | 8 | class Base64VLQ { 9 | 10 | public: 11 | 12 | std::string encode(const int number) const; 13 | 14 | private: 15 | 16 | char base64_encode(const int number) const; 17 | 18 | int to_vlq_signed(const int number) const; 19 | 20 | static const char* CHARACTERS; 21 | 22 | static const int VLQ_BASE_SHIFT; 23 | static const int VLQ_BASE; 24 | static const int VLQ_BASE_MASK; 25 | static const int VLQ_CONTINUATION_BIT; 26 | }; 27 | 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/libsass/src/bind.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_BIND_H 2 | #define SASS_BIND_H 3 | 4 | #include 5 | #include "environment.hpp" 6 | #include "ast_fwd_decl.hpp" 7 | 8 | namespace Sass { 9 | 10 | void bind(std::string type, std::string name, Parameters_Obj, Arguments_Obj, Context*, Env*, Eval*); 11 | } 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/libsass/src/c99func.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com) 3 | All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | 24 | #if defined(_MSC_VER) && _MSC_VER < 1900 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | static int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) 31 | { 32 | int count = -1; 33 | 34 | if (size != 0) 35 | count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); 36 | if (count == -1) 37 | count = _vscprintf(format, ap); 38 | 39 | return count; 40 | } 41 | 42 | int snprintf(char* str, size_t size, const char* format, ...) 43 | { 44 | int count; 45 | va_list ap; 46 | 47 | va_start(ap, format); 48 | count = c99_vsnprintf(str, size, format, ap); 49 | va_end(ap); 50 | 51 | return count; 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/libsass/src/check_nesting.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_CHECK_NESTING_H 2 | #define SASS_CHECK_NESTING_H 3 | 4 | #include "ast.hpp" 5 | #include "operation.hpp" 6 | 7 | namespace Sass { 8 | 9 | class CheckNesting : public Operation_CRTP { 10 | 11 | std::vector parents; 12 | Backtraces traces; 13 | Statement_Ptr parent; 14 | Definition_Ptr current_mixin_definition; 15 | 16 | Statement_Ptr fallback_impl(Statement_Ptr); 17 | Statement_Ptr before(Statement_Ptr); 18 | Statement_Ptr visit_children(Statement_Ptr); 19 | 20 | public: 21 | CheckNesting(); 22 | ~CheckNesting() { } 23 | 24 | Statement_Ptr operator()(Block_Ptr); 25 | Statement_Ptr operator()(Definition_Ptr); 26 | Statement_Ptr operator()(If_Ptr); 27 | 28 | template 29 | Statement_Ptr fallback(U x) { 30 | Statement_Ptr n = Cast(x); 31 | if (this->should_visit(n)) { 32 | return fallback_impl(n); 33 | } 34 | return NULL; 35 | } 36 | 37 | private: 38 | void invalid_content_parent(Statement_Ptr, AST_Node_Ptr); 39 | void invalid_charset_parent(Statement_Ptr, AST_Node_Ptr); 40 | void invalid_extend_parent(Statement_Ptr, AST_Node_Ptr); 41 | // void invalid_import_parent(Statement_Ptr); 42 | void invalid_mixin_definition_parent(Statement_Ptr, AST_Node_Ptr); 43 | void invalid_function_parent(Statement_Ptr, AST_Node_Ptr); 44 | 45 | void invalid_function_child(Statement_Ptr); 46 | void invalid_prop_child(Statement_Ptr); 47 | void invalid_prop_parent(Statement_Ptr, AST_Node_Ptr); 48 | void invalid_return_parent(Statement_Ptr, AST_Node_Ptr); 49 | void invalid_value_child(AST_Node_Ptr); 50 | 51 | bool is_transparent_parent(Statement_Ptr, Statement_Ptr); 52 | 53 | bool should_visit(Statement_Ptr); 54 | 55 | bool is_charset(Statement_Ptr); 56 | bool is_mixin(Statement_Ptr); 57 | bool is_function(Statement_Ptr); 58 | bool is_root_node(Statement_Ptr); 59 | bool is_at_root_node(Statement_Ptr); 60 | bool is_directive_node(Statement_Ptr); 61 | }; 62 | 63 | } 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/libsass/src/cssize.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_CSSIZE_H 2 | #define SASS_CSSIZE_H 3 | 4 | #include "ast.hpp" 5 | #include "context.hpp" 6 | #include "operation.hpp" 7 | #include "environment.hpp" 8 | 9 | namespace Sass { 10 | 11 | struct Backtrace; 12 | 13 | class Cssize : public Operation_CRTP { 14 | 15 | Context& ctx; 16 | Backtraces& traces; 17 | std::vector block_stack; 18 | std::vector p_stack; 19 | 20 | Statement_Ptr fallback_impl(AST_Node_Ptr n); 21 | 22 | public: 23 | Cssize(Context&); 24 | ~Cssize() { } 25 | 26 | Selector_List_Ptr selector(); 27 | 28 | Block_Ptr operator()(Block_Ptr); 29 | Statement_Ptr operator()(Ruleset_Ptr); 30 | // Statement_Ptr operator()(Bubble_Ptr); 31 | Statement_Ptr operator()(Media_Block_Ptr); 32 | Statement_Ptr operator()(Supports_Block_Ptr); 33 | Statement_Ptr operator()(At_Root_Block_Ptr); 34 | Statement_Ptr operator()(Directive_Ptr); 35 | Statement_Ptr operator()(Keyframe_Rule_Ptr); 36 | Statement_Ptr operator()(Trace_Ptr); 37 | Statement_Ptr operator()(Declaration_Ptr); 38 | // Statement_Ptr operator()(Assignment_Ptr); 39 | // Statement_Ptr operator()(Import_Ptr); 40 | // Statement_Ptr operator()(Import_Stub_Ptr); 41 | // Statement_Ptr operator()(Warning_Ptr); 42 | // Statement_Ptr operator()(Error_Ptr); 43 | // Statement_Ptr operator()(Comment_Ptr); 44 | // Statement_Ptr operator()(If_Ptr); 45 | // Statement_Ptr operator()(For_Ptr); 46 | // Statement_Ptr operator()(Each_Ptr); 47 | // Statement_Ptr operator()(While_Ptr); 48 | // Statement_Ptr operator()(Return_Ptr); 49 | // Statement_Ptr operator()(Extension_Ptr); 50 | // Statement_Ptr operator()(Definition_Ptr); 51 | // Statement_Ptr operator()(Mixin_Call_Ptr); 52 | // Statement_Ptr operator()(Content_Ptr); 53 | Statement_Ptr operator()(Null_Ptr); 54 | 55 | Statement_Ptr parent(); 56 | std::vector> slice_by_bubble(Block_Ptr); 57 | Statement_Ptr bubble(Directive_Ptr); 58 | Statement_Ptr bubble(At_Root_Block_Ptr); 59 | Statement_Ptr bubble(Media_Block_Ptr); 60 | Statement_Ptr bubble(Supports_Block_Ptr); 61 | 62 | Block_Ptr debubble(Block_Ptr children, Statement_Ptr parent = 0); 63 | Block_Ptr flatten(Block_Ptr); 64 | bool bubblable(Statement_Ptr); 65 | 66 | List_Ptr merge_media_queries(Media_Block_Ptr, Media_Block_Ptr); 67 | Media_Query_Ptr merge_media_query(Media_Query_Ptr, Media_Query_Ptr); 68 | 69 | template 70 | Statement_Ptr fallback(U x) { return fallback_impl(x); } 71 | 72 | void append_block(Block_Ptr, Block_Ptr); 73 | }; 74 | 75 | } 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /src/libsass/src/debug.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_DEBUG_H 2 | #define SASS_DEBUG_H 3 | 4 | #include 5 | 6 | #ifndef UINT32_MAX 7 | #define UINT32_MAX 0xffffffffU 8 | #endif 9 | 10 | enum dbg_lvl_t : uint32_t { 11 | NONE = 0, 12 | TRIM = 1, 13 | CHUNKS = 2, 14 | SUBWEAVE = 4, 15 | WEAVE = 8, 16 | EXTEND_COMPOUND = 16, 17 | EXTEND_COMPLEX = 32, 18 | LCS = 64, 19 | EXTEND_OBJECT = 128, 20 | ALL = UINT32_MAX 21 | }; 22 | 23 | #ifdef DEBUG 24 | 25 | #ifndef DEBUG_LVL 26 | const uint32_t debug_lvl = UINT32_MAX; 27 | #else 28 | const uint32_t debug_lvl = (DEBUG_LVL); 29 | #endif // DEBUG_LVL 30 | 31 | #define DEBUG_PRINT(lvl, x) if((lvl) & debug_lvl) { std::cerr << x; } 32 | #define DEBUG_PRINTLN(lvl, x) if((lvl) & debug_lvl) { std::cerr << x << std::endl; } 33 | #define DEBUG_EXEC(lvl, x) if((lvl) & debug_lvl) { x; } 34 | 35 | #else // DEBUG 36 | 37 | #define DEBUG_PRINT(lvl, x) 38 | #define DEBUG_PRINTLN(lvl, x) 39 | #define DEBUG_EXEC(lvl, x) 40 | 41 | #endif // DEBUG 42 | 43 | #endif // SASS_DEBUG 44 | -------------------------------------------------------------------------------- /src/libsass/src/expand.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_EXPAND_H 2 | #define SASS_EXPAND_H 3 | 4 | #include 5 | 6 | #include "ast.hpp" 7 | #include "eval.hpp" 8 | #include "operation.hpp" 9 | #include "environment.hpp" 10 | 11 | namespace Sass { 12 | 13 | class Listize; 14 | class Context; 15 | class Eval; 16 | struct Backtrace; 17 | 18 | class Expand : public Operation_CRTP { 19 | public: 20 | 21 | Env* environment(); 22 | Selector_List_Obj selector(); 23 | 24 | Context& ctx; 25 | Backtraces& traces; 26 | Eval eval; 27 | size_t recursions; 28 | bool in_keyframes; 29 | bool at_root_without_rule; 30 | bool old_at_root_without_rule; 31 | 32 | // it's easier to work with vectors 33 | std::vector env_stack; 34 | std::vector block_stack; 35 | std::vector call_stack; 36 | std::vector selector_stack; 37 | std::vector media_block_stack; 38 | 39 | Boolean_Obj bool_true; 40 | 41 | Statement_Ptr fallback_impl(AST_Node_Ptr n); 42 | 43 | private: 44 | void expand_selector_list(Selector_Obj, Selector_List_Obj extender); 45 | 46 | public: 47 | Expand(Context&, Env*, std::vector* stack = NULL); 48 | ~Expand() { } 49 | 50 | Block_Ptr operator()(Block_Ptr); 51 | Statement_Ptr operator()(Ruleset_Ptr); 52 | Statement_Ptr operator()(Media_Block_Ptr); 53 | Statement_Ptr operator()(Supports_Block_Ptr); 54 | Statement_Ptr operator()(At_Root_Block_Ptr); 55 | Statement_Ptr operator()(Directive_Ptr); 56 | Statement_Ptr operator()(Declaration_Ptr); 57 | Statement_Ptr operator()(Assignment_Ptr); 58 | Statement_Ptr operator()(Import_Ptr); 59 | Statement_Ptr operator()(Import_Stub_Ptr); 60 | Statement_Ptr operator()(Warning_Ptr); 61 | Statement_Ptr operator()(Error_Ptr); 62 | Statement_Ptr operator()(Debug_Ptr); 63 | Statement_Ptr operator()(Comment_Ptr); 64 | Statement_Ptr operator()(If_Ptr); 65 | Statement_Ptr operator()(For_Ptr); 66 | Statement_Ptr operator()(Each_Ptr); 67 | Statement_Ptr operator()(While_Ptr); 68 | Statement_Ptr operator()(Return_Ptr); 69 | Statement_Ptr operator()(Extension_Ptr); 70 | Statement_Ptr operator()(Definition_Ptr); 71 | Statement_Ptr operator()(Mixin_Call_Ptr); 72 | Statement_Ptr operator()(Content_Ptr); 73 | 74 | template 75 | Statement_Ptr fallback(U x) { return fallback_impl(x); } 76 | 77 | void append_block(Block_Ptr); 78 | }; 79 | 80 | } 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/libsass/src/kwd_arg_macros.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_KWD_ARG_MACROS_H 2 | #define SASS_KWD_ARG_MACROS_H 3 | 4 | // Example usage: 5 | // KWD_ARG_SET(Args) { 6 | // KWD_ARG(Args, string, foo); 7 | // KWD_ARG(Args, int, bar); 8 | // ... 9 | // }; 10 | // 11 | // ... and later ... 12 | // 13 | // something(Args().foo("hey").bar(3)); 14 | 15 | #define KWD_ARG_SET(set_name) class set_name 16 | 17 | #define KWD_ARG(set_name, type, name) \ 18 | private: \ 19 | type name##_; \ 20 | public: \ 21 | set_name& name(type name##__) { \ 22 | name##_ = name##__; \ 23 | return *this; \ 24 | } \ 25 | type name() { return name##_; } \ 26 | private: 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/libsass/src/listize.cpp: -------------------------------------------------------------------------------- 1 | #include "sass.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | #include "listize.hpp" 7 | #include "context.hpp" 8 | #include "backtrace.hpp" 9 | #include "error_handling.hpp" 10 | 11 | namespace Sass { 12 | 13 | Listize::Listize() 14 | { } 15 | 16 | Expression_Ptr Listize::operator()(Selector_List_Ptr sel) 17 | { 18 | List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA); 19 | l->from_selector(true); 20 | for (size_t i = 0, L = sel->length(); i < L; ++i) { 21 | if (!sel->at(i)) continue; 22 | l->append(sel->at(i)->perform(this)); 23 | } 24 | if (l->length()) return l.detach(); 25 | return SASS_MEMORY_NEW(Null, l->pstate()); 26 | } 27 | 28 | Expression_Ptr Listize::operator()(Compound_Selector_Ptr sel) 29 | { 30 | std::string str; 31 | for (size_t i = 0, L = sel->length(); i < L; ++i) { 32 | Expression_Ptr e = (*sel)[i]->perform(this); 33 | if (e) str += e->to_string(); 34 | } 35 | return SASS_MEMORY_NEW(String_Quoted, sel->pstate(), str); 36 | } 37 | 38 | Expression_Ptr Listize::operator()(Complex_Selector_Ptr sel) 39 | { 40 | List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), 2); 41 | l->from_selector(true); 42 | Compound_Selector_Obj head = sel->head(); 43 | if (head && !head->is_empty_reference()) 44 | { 45 | Expression_Ptr hh = head->perform(this); 46 | if (hh) l->append(hh); 47 | } 48 | 49 | std::string reference = ! sel->reference() ? "" 50 | : sel->reference()->to_string(); 51 | switch(sel->combinator()) 52 | { 53 | case Complex_Selector::PARENT_OF: 54 | l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), ">")); 55 | break; 56 | case Complex_Selector::ADJACENT_TO: 57 | l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "+")); 58 | break; 59 | case Complex_Selector::REFERENCE: 60 | l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "/" + reference + "/")); 61 | break; 62 | case Complex_Selector::PRECEDES: 63 | l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "~")); 64 | break; 65 | case Complex_Selector::ANCESTOR_OF: 66 | break; 67 | default: break; 68 | } 69 | 70 | Complex_Selector_Obj tail = sel->tail(); 71 | if (tail) 72 | { 73 | Expression_Obj tt = tail->perform(this); 74 | if (List_Ptr ls = Cast(tt)) 75 | { l->concat(ls); } 76 | } 77 | if (l->length() == 0) return 0; 78 | return l.detach(); 79 | } 80 | 81 | Expression_Ptr Listize::fallback_impl(AST_Node_Ptr n) 82 | { 83 | return Cast(n); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/libsass/src/listize.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_LISTIZE_H 2 | #define SASS_LISTIZE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "ast.hpp" 8 | #include "context.hpp" 9 | #include "operation.hpp" 10 | #include "environment.hpp" 11 | 12 | namespace Sass { 13 | 14 | struct Backtrace; 15 | 16 | class Listize : public Operation_CRTP { 17 | 18 | Expression_Ptr fallback_impl(AST_Node_Ptr n); 19 | 20 | public: 21 | Listize(); 22 | ~Listize() { } 23 | 24 | Expression_Ptr operator()(Selector_List_Ptr); 25 | Expression_Ptr operator()(Complex_Selector_Ptr); 26 | Expression_Ptr operator()(Compound_Selector_Ptr); 27 | 28 | template 29 | Expression_Ptr fallback(U x) { return fallback_impl(x); } 30 | }; 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/libsass/src/mapping.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_MAPPING_H 2 | #define SASS_MAPPING_H 3 | 4 | #include "position.hpp" 5 | 6 | namespace Sass { 7 | 8 | struct Mapping { 9 | Position original_position; 10 | Position generated_position; 11 | 12 | Mapping(const Position& original_position, const Position& generated_position) 13 | : original_position(original_position), generated_position(generated_position) { } 14 | }; 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/libsass/src/operators.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_OPERATORS_H 2 | #define SASS_OPERATORS_H 3 | 4 | #include "values.hpp" 5 | #include "sass/values.h" 6 | 7 | namespace Sass { 8 | 9 | namespace Operators { 10 | 11 | // equality operator using AST Node operator== 12 | bool eq(Expression_Obj, Expression_Obj); 13 | bool neq(Expression_Obj, Expression_Obj); 14 | // specific operators based on cmp and eq 15 | bool lt(Expression_Obj, Expression_Obj); 16 | bool gt(Expression_Obj, Expression_Obj); 17 | bool lte(Expression_Obj, Expression_Obj); 18 | bool gte(Expression_Obj, Expression_Obj); 19 | // arithmetic for all the combinations that matter 20 | Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); 21 | Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); 22 | Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); 23 | Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); 24 | Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); 25 | 26 | }; 27 | 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/libsass/src/output.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_OUTPUT_H 2 | #define SASS_OUTPUT_H 3 | 4 | #include 5 | #include 6 | 7 | #include "util.hpp" 8 | #include "inspect.hpp" 9 | #include "operation.hpp" 10 | 11 | namespace Sass { 12 | class Context; 13 | 14 | // Refactor to make it generic to find linefeed (look behind) 15 | inline bool ends_with(std::string const & value, std::string const & ending) 16 | { 17 | if (ending.size() > value.size()) return false; 18 | return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); 19 | } 20 | 21 | class Output : public Inspect { 22 | protected: 23 | using Inspect::operator(); 24 | 25 | public: 26 | Output(Sass_Output_Options& opt); 27 | virtual ~Output(); 28 | 29 | protected: 30 | std::string charset; 31 | std::vector top_nodes; 32 | 33 | public: 34 | OutputBuffer get_buffer(void); 35 | 36 | virtual void operator()(Map_Ptr); 37 | virtual void operator()(Ruleset_Ptr); 38 | virtual void operator()(Supports_Block_Ptr); 39 | virtual void operator()(Media_Block_Ptr); 40 | virtual void operator()(Directive_Ptr); 41 | virtual void operator()(Keyframe_Rule_Ptr); 42 | virtual void operator()(Import_Ptr); 43 | virtual void operator()(Comment_Ptr); 44 | virtual void operator()(Number_Ptr); 45 | virtual void operator()(String_Quoted_Ptr); 46 | virtual void operator()(String_Constant_Ptr); 47 | 48 | void fallback_impl(AST_Node_Ptr n); 49 | 50 | }; 51 | 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/libsass/src/paths.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_PATHS_H 2 | #define SASS_PATHS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | template 10 | std::string vector_to_string(std::vector v) 11 | { 12 | std::stringstream buffer; 13 | buffer << "["; 14 | 15 | if (!v.empty()) 16 | { buffer << v[0]; } 17 | else 18 | { buffer << "]"; } 19 | 20 | if (v.size() == 1) 21 | { buffer << "]"; } 22 | else 23 | { 24 | for (size_t i = 1, S = v.size(); i < S; ++i) buffer << ", " << v[i]; 25 | buffer << "]"; 26 | } 27 | 28 | return buffer.str(); 29 | } 30 | 31 | namespace Sass { 32 | 33 | 34 | template 35 | std::vector > paths(std::vector > strata, size_t from_end = 0) 36 | { 37 | if (strata.empty()) { 38 | return std::vector >(); 39 | } 40 | 41 | size_t end = strata.size() - from_end; 42 | if (end <= 1) { 43 | std::vector > starting_points; 44 | starting_points.reserve(strata[0].size()); 45 | for (size_t i = 0, S = strata[0].size(); i < S; ++i) { 46 | std::vector starting_point; 47 | starting_point.push_back(strata[0][i]); 48 | starting_points.push_back(starting_point); 49 | } 50 | return starting_points; 51 | } 52 | 53 | std::vector > up_to_here = paths(strata, from_end + 1); 54 | std::vector here = strata[end-1]; 55 | 56 | std::vector > branches; 57 | branches.reserve(up_to_here.size() * here.size()); 58 | for (size_t i = 0, S1 = up_to_here.size(); i < S1; ++i) { 59 | for (size_t j = 0, S2 = here.size(); j < S2; ++j) { 60 | std::vector branch = up_to_here[i]; 61 | branch.push_back(here[j]); 62 | branches.push_back(branch); 63 | } 64 | } 65 | 66 | return branches; 67 | } 68 | 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/libsass/src/plugins.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_PLUGINS_H 2 | #define SASS_PLUGINS_H 3 | 4 | #include 5 | #include 6 | #include "utf8_string.hpp" 7 | #include "sass/functions.h" 8 | 9 | #ifdef _WIN32 10 | 11 | #define LOAD_LIB(var, path) HMODULE var = LoadLibraryW(UTF_8::convert_to_utf16(path).c_str()) 12 | #define LOAD_LIB_WCHR(var, path_wide_str) HMODULE var = LoadLibraryW(path_wide_str.c_str()) 13 | #define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name) 14 | #define CLOSE_LIB(var) FreeLibrary(var) 15 | 16 | #ifndef dlerror 17 | #define dlerror() 0 18 | #endif 19 | 20 | #else 21 | 22 | #define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY) 23 | #define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name) 24 | #define CLOSE_LIB(var) dlclose(var) 25 | 26 | #endif 27 | 28 | namespace Sass { 29 | 30 | 31 | class Plugins { 32 | 33 | public: // c-tor 34 | Plugins(void); 35 | ~Plugins(void); 36 | 37 | public: // methods 38 | // load one specific plugin 39 | bool load_plugin(const std::string& path); 40 | // load all plugins from a directory 41 | size_t load_plugins(const std::string& path); 42 | 43 | public: // public accessors 44 | const std::vector get_headers(void) { return headers; } 45 | const std::vector get_importers(void) { return importers; } 46 | const std::vector get_functions(void) { return functions; } 47 | 48 | private: // private vars 49 | std::vector headers; 50 | std::vector importers; 51 | std::vector functions; 52 | 53 | }; 54 | 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/libsass/src/remove_placeholders.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_REMOVE_PLACEHOLDERS_H 2 | #define SASS_REMOVE_PLACEHOLDERS_H 3 | 4 | #pragma once 5 | 6 | #include "ast.hpp" 7 | #include "operation.hpp" 8 | 9 | namespace Sass { 10 | 11 | 12 | class Remove_Placeholders : public Operation_CRTP { 13 | 14 | void fallback_impl(AST_Node_Ptr n) {} 15 | 16 | public: 17 | Selector_List_Ptr remove_placeholders(Selector_List_Ptr); 18 | 19 | public: 20 | Remove_Placeholders(); 21 | ~Remove_Placeholders() { } 22 | 23 | void operator()(Block_Ptr); 24 | void operator()(Ruleset_Ptr); 25 | void operator()(Media_Block_Ptr); 26 | void operator()(Supports_Block_Ptr); 27 | void operator()(Directive_Ptr); 28 | 29 | template 30 | void fallback(U x) { return fallback_impl(x); } 31 | }; 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/libsass/src/sass_functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SASS_FUNCTIONS_H 2 | #define SASS_SASS_FUNCTIONS_H 3 | 4 | #include "sass.h" 5 | #include "environment.hpp" 6 | #include "functions.hpp" 7 | 8 | // Struct to hold custom function callback 9 | struct Sass_Function { 10 | char* signature; 11 | Sass_Function_Fn function; 12 | void* cookie; 13 | }; 14 | 15 | // External import entry 16 | struct Sass_Import { 17 | char* imp_path; // path as found in the import statement 18 | char *abs_path; // path after importer has resolved it 19 | char* source; 20 | char* srcmap; 21 | // error handling 22 | char* error; 23 | size_t line; 24 | size_t column; 25 | }; 26 | 27 | // External environments 28 | struct Sass_Env { 29 | // links to parent frames 30 | Sass::Env* frame; 31 | }; 32 | 33 | // External call entry 34 | struct Sass_Callee { 35 | const char* name; 36 | const char* path; 37 | size_t line; 38 | size_t column; 39 | enum Sass_Callee_Type type; 40 | struct Sass_Env env; 41 | }; 42 | 43 | // Struct to hold importer callback 44 | struct Sass_Importer { 45 | Sass_Importer_Fn importer; 46 | double priority; 47 | void* cookie; 48 | }; 49 | 50 | #endif -------------------------------------------------------------------------------- /src/libsass/src/sass_values.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SASS_VALUES_H 2 | #define SASS_SASS_VALUES_H 3 | 4 | #include "sass.h" 5 | 6 | struct Sass_Unknown { 7 | enum Sass_Tag tag; 8 | }; 9 | 10 | struct Sass_Boolean { 11 | enum Sass_Tag tag; 12 | bool value; 13 | }; 14 | 15 | struct Sass_Number { 16 | enum Sass_Tag tag; 17 | double value; 18 | char* unit; 19 | }; 20 | 21 | struct Sass_Color { 22 | enum Sass_Tag tag; 23 | double r; 24 | double g; 25 | double b; 26 | double a; 27 | }; 28 | 29 | struct Sass_String { 30 | enum Sass_Tag tag; 31 | bool quoted; 32 | char* value; 33 | }; 34 | 35 | struct Sass_List { 36 | enum Sass_Tag tag; 37 | enum Sass_Separator separator; 38 | bool is_bracketed; 39 | size_t length; 40 | // null terminated "array" 41 | union Sass_Value** values; 42 | }; 43 | 44 | struct Sass_Map { 45 | enum Sass_Tag tag; 46 | size_t length; 47 | struct Sass_MapPair* pairs; 48 | }; 49 | 50 | struct Sass_Null { 51 | enum Sass_Tag tag; 52 | }; 53 | 54 | struct Sass_Error { 55 | enum Sass_Tag tag; 56 | char* message; 57 | }; 58 | 59 | struct Sass_Warning { 60 | enum Sass_Tag tag; 61 | char* message; 62 | }; 63 | 64 | union Sass_Value { 65 | struct Sass_Unknown unknown; 66 | struct Sass_Boolean boolean; 67 | struct Sass_Number number; 68 | struct Sass_Color color; 69 | struct Sass_String string; 70 | struct Sass_List list; 71 | struct Sass_Map map; 72 | struct Sass_Null null; 73 | struct Sass_Error error; 74 | struct Sass_Warning warning; 75 | }; 76 | 77 | struct Sass_MapPair { 78 | union Sass_Value* key; 79 | union Sass_Value* value; 80 | }; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/libsass/src/source_map.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SOURCE_MAP_H 2 | #define SASS_SOURCE_MAP_H 3 | 4 | #include 5 | #include 6 | 7 | #include "ast_fwd_decl.hpp" 8 | #include "base64vlq.hpp" 9 | #include "position.hpp" 10 | #include "mapping.hpp" 11 | 12 | #define VECTOR_PUSH(vec, ins) vec.insert(vec.end(), ins.begin(), ins.end()) 13 | #define VECTOR_UNSHIFT(vec, ins) vec.insert(vec.begin(), ins.begin(), ins.end()) 14 | 15 | namespace Sass { 16 | 17 | class Context; 18 | class OutputBuffer; 19 | 20 | class SourceMap { 21 | 22 | public: 23 | std::vector source_index; 24 | SourceMap(); 25 | SourceMap(const std::string& file); 26 | 27 | void append(const Offset& offset); 28 | void prepend(const Offset& offset); 29 | void append(const OutputBuffer& out); 30 | void prepend(const OutputBuffer& out); 31 | void add_open_mapping(const AST_Node_Ptr node); 32 | void add_close_mapping(const AST_Node_Ptr node); 33 | 34 | std::string render_srcmap(Context &ctx); 35 | ParserState remap(const ParserState& pstate); 36 | 37 | private: 38 | 39 | std::string serialize_mappings(); 40 | 41 | std::vector mappings; 42 | Position current_position; 43 | public: 44 | std::string file; 45 | private: 46 | Base64VLQ base64vlq; 47 | }; 48 | 49 | class OutputBuffer { 50 | public: 51 | OutputBuffer(void) 52 | : buffer(""), 53 | smap() 54 | { } 55 | public: 56 | std::string buffer; 57 | SourceMap smap; 58 | }; 59 | 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/libsass/src/subset_map.cpp: -------------------------------------------------------------------------------- 1 | #include "sass.hpp" 2 | #include "ast.hpp" 3 | #include "subset_map.hpp" 4 | 5 | namespace Sass { 6 | 7 | void Subset_Map::put(const Compound_Selector_Obj& sel, const SubSetMapPair& value) 8 | { 9 | if (sel->empty()) throw std::runtime_error("internal error: subset map keys may not be empty"); 10 | size_t index = values_.size(); 11 | values_.push_back(value); 12 | for (size_t i = 0, S = sel->length(); i < S; ++i) 13 | { 14 | hash_[(*sel)[i]].push_back(std::make_pair(sel, index)); 15 | } 16 | } 17 | 18 | std::vector Subset_Map::get_kv(const Compound_Selector_Obj& sel) 19 | { 20 | SimpleSelectorDict dict(sel->begin(), sel->end()); // XXX Set 21 | std::vector indices; 22 | for (size_t i = 0, S = sel->length(); i < S; ++i) { 23 | if (!hash_.count((*sel)[i])) { 24 | continue; 25 | } 26 | const std::vector >& subsets = hash_[(*sel)[i]]; 27 | for (const std::pair& item : subsets) { 28 | bool include = true; 29 | for (const Simple_Selector_Obj& it : item.first->elements()) { 30 | auto found = dict.find(it); 31 | if (found == dict.end()) { 32 | include = false; 33 | break; 34 | } 35 | } 36 | if (include) indices.push_back(item.second); 37 | } 38 | } 39 | sort(indices.begin(), indices.end()); 40 | std::vector::iterator indices_end = unique(indices.begin(), indices.end()); 41 | indices.resize(distance(indices.begin(), indices_end)); 42 | 43 | std::vector results; 44 | for (size_t i = 0, S = indices.size(); i < S; ++i) { 45 | results.push_back(values_[indices[i]]); 46 | } 47 | return results; 48 | } 49 | 50 | std::vector Subset_Map::get_v(const Compound_Selector_Obj& sel) 51 | { 52 | return get_kv(sel); 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /src/libsass/src/subset_map.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SUBSET_MAP_H 2 | #define SASS_SUBSET_MAP_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "ast_fwd_decl.hpp" 11 | 12 | 13 | // #include 14 | // #include 15 | // template 16 | // std::string vector_to_string(std::vector v) 17 | // { 18 | // std::stringstream buffer; 19 | // buffer << "["; 20 | 21 | // if (!v.empty()) 22 | // { buffer << v[0]; } 23 | // else 24 | // { buffer << "]"; } 25 | 26 | // if (v.size() == 1) 27 | // { buffer << "]"; } 28 | // else 29 | // { 30 | // for (size_t i = 1, S = v.size(); i < S; ++i) buffer << ", " << v[i]; 31 | // buffer << "]"; 32 | // } 33 | 34 | // return buffer.str(); 35 | // } 36 | 37 | // template 38 | // std::string set_to_string(set v) 39 | // { 40 | // std::stringstream buffer; 41 | // buffer << "["; 42 | // typename std::set::iterator i = v.begin(); 43 | // if (!v.empty()) 44 | // { buffer << *i; } 45 | // else 46 | // { buffer << "]"; } 47 | 48 | // if (v.size() == 1) 49 | // { buffer << "]"; } 50 | // else 51 | // { 52 | // for (++i; i != v.end(); ++i) buffer << ", " << *i; 53 | // buffer << "]"; 54 | // } 55 | 56 | // return buffer.str(); 57 | // } 58 | 59 | namespace Sass { 60 | 61 | class Subset_Map { 62 | private: 63 | std::vector values_; 64 | std::map >, OrderNodes > hash_; 65 | public: 66 | void put(const Compound_Selector_Obj& sel, const SubSetMapPair& value); 67 | std::vector get_kv(const Compound_Selector_Obj& s); 68 | std::vector get_v(const Compound_Selector_Obj& s); 69 | bool empty() { return values_.empty(); } 70 | void clear() { values_.clear(); hash_.clear(); } 71 | const std::vector values(void) { return values_; } 72 | }; 73 | 74 | } 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/libsass/src/support/libsass.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libsass 7 | URL: https://github.com/sass/libsass 8 | Description: A C implementation of a Sass compiler 9 | Version: @VERSION@ 10 | Libs: -L${libdir} -lsass 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /src/libsass/src/to_c.cpp: -------------------------------------------------------------------------------- 1 | #include "sass.hpp" 2 | #include "to_c.hpp" 3 | #include "ast.hpp" 4 | 5 | namespace Sass { 6 | 7 | union Sass_Value* To_C::fallback_impl(AST_Node_Ptr n) 8 | { return sass_make_error("unknown type for C-API"); } 9 | 10 | union Sass_Value* To_C::operator()(Boolean_Ptr b) 11 | { return sass_make_boolean(b->value()); } 12 | 13 | union Sass_Value* To_C::operator()(Number_Ptr n) 14 | { return sass_make_number(n->value(), n->unit().c_str()); } 15 | 16 | union Sass_Value* To_C::operator()(Custom_Warning_Ptr w) 17 | { return sass_make_warning(w->message().c_str()); } 18 | 19 | union Sass_Value* To_C::operator()(Custom_Error_Ptr e) 20 | { return sass_make_error(e->message().c_str()); } 21 | 22 | union Sass_Value* To_C::operator()(Color_Ptr c) 23 | { return sass_make_color(c->r(), c->g(), c->b(), c->a()); } 24 | 25 | union Sass_Value* To_C::operator()(String_Constant_Ptr s) 26 | { 27 | if (s->quote_mark()) { 28 | return sass_make_qstring(s->value().c_str()); 29 | } else { 30 | return sass_make_string(s->value().c_str()); 31 | } 32 | } 33 | 34 | union Sass_Value* To_C::operator()(String_Quoted_Ptr s) 35 | { return sass_make_qstring(s->value().c_str()); } 36 | 37 | union Sass_Value* To_C::operator()(List_Ptr l) 38 | { 39 | union Sass_Value* v = sass_make_list(l->length(), l->separator(), l->is_bracketed()); 40 | for (size_t i = 0, L = l->length(); i < L; ++i) { 41 | sass_list_set_value(v, i, (*l)[i]->perform(this)); 42 | } 43 | return v; 44 | } 45 | 46 | union Sass_Value* To_C::operator()(Map_Ptr m) 47 | { 48 | union Sass_Value* v = sass_make_map(m->length()); 49 | int i = 0; 50 | for (auto key : m->keys()) { 51 | sass_map_set_key(v, i, key->perform(this)); 52 | sass_map_set_value(v, i, m->at(key)->perform(this)); 53 | i++; 54 | } 55 | return v; 56 | } 57 | 58 | union Sass_Value* To_C::operator()(Arguments_Ptr a) 59 | { 60 | union Sass_Value* v = sass_make_list(a->length(), SASS_COMMA, false); 61 | for (size_t i = 0, L = a->length(); i < L; ++i) { 62 | sass_list_set_value(v, i, (*a)[i]->perform(this)); 63 | } 64 | return v; 65 | } 66 | 67 | union Sass_Value* To_C::operator()(Argument_Ptr a) 68 | { return a->value()->perform(this); } 69 | 70 | // not strictly necessary because of the fallback 71 | union Sass_Value* To_C::operator()(Null_Ptr n) 72 | { return sass_make_null(); } 73 | 74 | }; 75 | -------------------------------------------------------------------------------- /src/libsass/src/to_c.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TO_C_H 2 | #define SASS_TO_C_H 3 | 4 | #include "ast_fwd_decl.hpp" 5 | #include "operation.hpp" 6 | #include "sass/values.h" 7 | 8 | namespace Sass { 9 | 10 | class To_C : public Operation_CRTP { 11 | // override this to define a catch-all 12 | union Sass_Value* fallback_impl(AST_Node_Ptr n); 13 | 14 | public: 15 | 16 | To_C() { } 17 | ~To_C() { } 18 | 19 | union Sass_Value* operator()(Boolean_Ptr); 20 | union Sass_Value* operator()(Number_Ptr); 21 | union Sass_Value* operator()(Color_Ptr); 22 | union Sass_Value* operator()(String_Constant_Ptr); 23 | union Sass_Value* operator()(String_Quoted_Ptr); 24 | union Sass_Value* operator()(Custom_Warning_Ptr); 25 | union Sass_Value* operator()(Custom_Error_Ptr); 26 | union Sass_Value* operator()(List_Ptr); 27 | union Sass_Value* operator()(Map_Ptr); 28 | union Sass_Value* operator()(Null_Ptr); 29 | union Sass_Value* operator()(Arguments_Ptr); 30 | union Sass_Value* operator()(Argument_Ptr); 31 | 32 | // dispatch to fallback implementation 33 | union Sass_Value* fallback(AST_Node_Ptr x) 34 | { return fallback_impl(x); } 35 | }; 36 | 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/libsass/src/to_value.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TO_VALUE_H 2 | #define SASS_TO_VALUE_H 3 | 4 | #include "operation.hpp" 5 | #include "sass/values.h" 6 | #include "ast_fwd_decl.hpp" 7 | 8 | namespace Sass { 9 | 10 | class To_Value : public Operation_CRTP { 11 | 12 | Value_Ptr fallback_impl(AST_Node_Ptr n); 13 | 14 | private: 15 | 16 | Context& ctx; 17 | 18 | public: 19 | 20 | To_Value(Context& ctx) 21 | : ctx(ctx) 22 | { } 23 | ~To_Value() { } 24 | using Operation::operator(); 25 | 26 | Value_Ptr operator()(Argument_Ptr); 27 | Value_Ptr operator()(Boolean_Ptr); 28 | Value_Ptr operator()(Number_Ptr); 29 | Value_Ptr operator()(Color_Ptr); 30 | Value_Ptr operator()(String_Constant_Ptr); 31 | Value_Ptr operator()(String_Quoted_Ptr); 32 | Value_Ptr operator()(Custom_Warning_Ptr); 33 | Value_Ptr operator()(Custom_Error_Ptr); 34 | Value_Ptr operator()(List_Ptr); 35 | Value_Ptr operator()(Map_Ptr); 36 | Value_Ptr operator()(Null_Ptr); 37 | Value_Ptr operator()(Function_Ptr); 38 | 39 | // convert to string via `To_String` 40 | Value_Ptr operator()(Selector_List_Ptr); 41 | Value_Ptr operator()(Binary_Expression_Ptr); 42 | 43 | // fallback throws error 44 | template 45 | Value_Ptr fallback(U x) { return fallback_impl(x); } 46 | }; 47 | 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/libsass/src/utf8.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 30 | 31 | #include "utf8/checked.h" 32 | #include "utf8/unchecked.h" 33 | 34 | #endif // header guard 35 | -------------------------------------------------------------------------------- /src/libsass/src/utf8_string.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_UTF8_STRING_H 2 | #define SASS_UTF8_STRING_H 3 | 4 | #include 5 | #include "utf8.h" 6 | 7 | namespace Sass { 8 | namespace UTF_8 { 9 | 10 | // naming conventions: 11 | // offset: raw byte offset (0 based) 12 | // position: code point offset (0 based) 13 | // index: code point offset (1 based or negative) 14 | 15 | // function that will count the number of code points (utf-8 characters) from the beginning to the given end 16 | size_t code_point_count(const std::string& str, size_t start, size_t end); 17 | size_t code_point_count(const std::string& str); 18 | 19 | // function that will return the byte offset of a code point in a 20 | size_t offset_at_position(const std::string& str, size_t position); 21 | 22 | // function that returns number of bytes in a character in a string 23 | size_t code_point_size_at_offset(const std::string& str, size_t offset); 24 | 25 | // function that will return a normalized index, given a crazy one 26 | size_t normalize_index(int index, size_t len); 27 | 28 | #ifdef _WIN32 29 | // functions to handle unicode paths on windows 30 | std::string convert_from_utf16(const std::wstring& wstr); 31 | std::wstring convert_to_utf16(const std::string& str); 32 | #endif 33 | 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/libsass/src/util.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_UTIL_H 2 | #define SASS_UTIL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "sass.hpp" 8 | #include "sass/base.h" 9 | #include "ast_fwd_decl.hpp" 10 | 11 | #define SASS_ASSERT(cond, msg) assert(cond && msg) 12 | 13 | namespace Sass { 14 | 15 | double round(double val, size_t precision = 0); 16 | double sass_strtod(const char* str); 17 | const char* safe_str(const char *, const char* = ""); 18 | void free_string_array(char **); 19 | char **copy_strings(const std::vector&, char ***, int = 0); 20 | std::string read_css_string(const std::string& str, bool css = true); 21 | std::string evacuate_escapes(const std::string& str); 22 | std::string string_to_output(const std::string& str); 23 | std::string comment_to_string(const std::string& text); 24 | std::string read_hex_escapes(const std::string& str); 25 | std::string escape_string(const std::string& str); 26 | void newline_to_space(std::string& str); 27 | 28 | std::string quote(const std::string&, char q = 0); 29 | std::string unquote(const std::string&, char* q = 0, bool keep_utf8_sequences = false, bool strict = true); 30 | char detect_best_quotemark(const char* s, char qm = '"'); 31 | 32 | bool is_hex_doublet(double n); 33 | bool is_color_doublet(double r, double g, double b); 34 | 35 | bool peek_linefeed(const char* start); 36 | 37 | namespace Util { 38 | 39 | std::string rtrim(const std::string& str); 40 | 41 | std::string normalize_underscores(const std::string& str); 42 | std::string normalize_decimals(const std::string& str); 43 | 44 | bool isPrintable(Ruleset_Ptr r, Sass_Output_Style style = NESTED); 45 | bool isPrintable(Supports_Block_Ptr r, Sass_Output_Style style = NESTED); 46 | bool isPrintable(Media_Block_Ptr r, Sass_Output_Style style = NESTED); 47 | bool isPrintable(Comment_Ptr b, Sass_Output_Style style = NESTED); 48 | bool isPrintable(Block_Obj b, Sass_Output_Style style = NESTED); 49 | bool isPrintable(String_Constant_Ptr s, Sass_Output_Style style = NESTED); 50 | bool isPrintable(String_Quoted_Ptr s, Sass_Output_Style style = NESTED); 51 | bool isPrintable(Declaration_Ptr d, Sass_Output_Style style = NESTED); 52 | bool isAscii(const char chr); 53 | 54 | } 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /src/libsass/src/values.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_VALUES_H 2 | #define SASS_VALUES_H 3 | 4 | #include "ast.hpp" 5 | 6 | namespace Sass { 7 | 8 | union Sass_Value* ast_node_to_sass_value (const Expression_Ptr val); 9 | Value_Ptr sass_value_to_ast_node (const union Sass_Value* val); 10 | 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /src/libsass/test/test_node.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "node.hpp" 5 | #include "parser.hpp" 6 | 7 | 8 | #define STATIC_ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0]))) 9 | 10 | 11 | namespace Sass { 12 | 13 | Context ctx = Context::Data(); 14 | 15 | const char* const ROUNDTRIP_TESTS[] = { 16 | NULL, 17 | "~", 18 | "CMPD", 19 | "~ CMPD", 20 | "CMPD >", 21 | "> > CMPD", 22 | "CMPD ~ ~", 23 | "> + CMPD1.CMPD2 > ~", 24 | "> + CMPD1.CMPD2 CMPD3.CMPD4 > ~", 25 | "+ CMPD1 CMPD2 ~ CMPD3 + CMPD4 > CMPD5 > ~" 26 | }; 27 | 28 | 29 | 30 | static Complex_Selector* createComplexSelector(std::string src) { 31 | std::string temp(src); 32 | temp += ";"; 33 | return (*Parser::from_c_str(temp.c_str(), ctx, "", Position()).parse_selector_list())[0]; 34 | } 35 | 36 | 37 | void roundtripTest(const char* toTest) { 38 | 39 | // Create the initial selector 40 | 41 | Complex_Selector* pOrigSelector = NULL; 42 | if (toTest) { 43 | pOrigSelector = createComplexSelector(toTest); 44 | } 45 | 46 | std::string expected(pOrigSelector ? pOrigSelector->to_string() : "NULL"); 47 | 48 | 49 | // Roundtrip the selector into a node and back 50 | 51 | Node node = complexSelectorToNode(pOrigSelector, ctx); 52 | 53 | std::stringstream nodeStringStream; 54 | nodeStringStream << node; 55 | std::string nodeString = nodeStringStream.str(); 56 | cout << "ASNODE: " << node << endl; 57 | 58 | Complex_Selector* pNewSelector = nodeToComplexSelector(node, ctx); 59 | 60 | // Show the result 61 | 62 | std::string result(pNewSelector ? pNewSelector->to_string() : "NULL"); 63 | 64 | cout << "SELECTOR: " << expected << endl; 65 | cout << "NEW SELECTOR: " << result << endl; 66 | 67 | 68 | // Test that they are equal using the equality operator 69 | 70 | assert( (!pOrigSelector && !pNewSelector ) || (pOrigSelector && pNewSelector) ); 71 | if (pOrigSelector) { 72 | assert( *pOrigSelector == *pNewSelector ); 73 | } 74 | 75 | 76 | // Test that they are equal by comparing the string versions of the selectors 77 | 78 | assert(expected == result); 79 | 80 | } 81 | 82 | 83 | int main() { 84 | for (int index = 0; index < STATIC_ARRAY_SIZE(ROUNDTRIP_TESTS); index++) { 85 | const char* const toTest = ROUNDTRIP_TESTS[index]; 86 | cout << "\nINPUT STRING: " << (toTest ? toTest : "NULL") << endl; 87 | roundtripTest(toTest); 88 | } 89 | 90 | cout << "\nTesting Done.\n"; 91 | } 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/libsass/test/test_paths.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../paths.hpp" 3 | 4 | using namespace Sass; 5 | 6 | template 7 | std::vector& operator<<(std::vector& v, const T& e) 8 | { 9 | v.push_back(e); 10 | return v; 11 | } 12 | 13 | int main() 14 | { 15 | std::vector v1, v2, v3; 16 | v1 << 1 << 2; 17 | v2 << 3; 18 | v3 << 4 << 5 << 6; 19 | 20 | std::vector > ss; 21 | ss << v1 << v2 << v3; 22 | 23 | std::vector > ps = paths(ss); 24 | for (size_t i = 0, S = ps.size(); i < S; ++i) { 25 | std::cout << vector_to_string(ps[i]) << std::endl; 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /src/libsass/test/test_selector_difference.cpp: -------------------------------------------------------------------------------- 1 | #include "../ast.hpp" 2 | #include "../context.hpp" 3 | #include "../parser.hpp" 4 | #include 5 | #include 6 | 7 | using namespace Sass; 8 | 9 | Context ctx = Context::Data(); 10 | 11 | Compound_Selector* selector(std::string src) 12 | { return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_compound_selector(); } 13 | 14 | void diff(std::string s, std::string t) 15 | { 16 | std::cout << s << " - " << t << " = " << selector(s + ";")->minus(selector(t + ";"), ctx)->to_string() << std::endl; 17 | } 18 | 19 | int main() 20 | { 21 | diff(".a.b.c", ".c.b"); 22 | diff(".a.b.c", ".fludge.b"); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /src/libsass/test/test_specificity.cpp: -------------------------------------------------------------------------------- 1 | #include "../ast.hpp" 2 | #include "../context.hpp" 3 | #include "../parser.hpp" 4 | #include 5 | #include 6 | 7 | using namespace Sass; 8 | 9 | Context ctx = Context::Data(); 10 | 11 | Selector* selector(std::string src) 12 | { return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_selector_list(); } 13 | 14 | void spec(std::string sel) 15 | { std::cout << sel << "\t::\t" << selector(sel + ";")->specificity() << std::endl; } 16 | 17 | int main() 18 | { 19 | spec("foo bar hux"); 20 | spec(".foo .bar hux"); 21 | spec("#foo .bar[hux='mux']"); 22 | spec("a b c d e f"); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /src/libsass/test/test_superselector.cpp: -------------------------------------------------------------------------------- 1 | #include "../ast.hpp" 2 | #include "../context.hpp" 3 | #include "../parser.hpp" 4 | #include 5 | 6 | using namespace Sass; 7 | 8 | Context ctx = Context(Context::Data()); 9 | 10 | Compound_Selector* compound_selector(std::string src) 11 | { return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_compound_selector(); } 12 | 13 | Complex_Selector* complex_selector(std::string src) 14 | { return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_complex_selector(false); } 15 | 16 | void check_compound(std::string s1, std::string s2) 17 | { 18 | std::cout << "Is " 19 | << s1 20 | << " a superselector of " 21 | << s2 22 | << "?\t" 23 | << compound_selector(s1 + ";")->is_superselector_of(compound_selector(s2 + ";")) 24 | << std::endl; 25 | } 26 | 27 | void check_complex(std::string s1, std::string s2) 28 | { 29 | std::cout << "Is " 30 | << s1 31 | << " a superselector of " 32 | << s2 33 | << "?\t" 34 | << complex_selector(s1 + ";")->is_superselector_of(complex_selector(s2 + ";")) 35 | << std::endl; 36 | } 37 | 38 | int main() 39 | { 40 | check_compound(".foo", ".foo.bar"); 41 | check_compound(".foo.bar", ".foo"); 42 | check_compound(".foo.bar", "div.foo"); 43 | check_compound(".foo", "div.foo"); 44 | check_compound("div.foo", ".foo"); 45 | check_compound("div.foo", "div.bar.foo"); 46 | check_compound("p.foo", "div.bar.foo"); 47 | check_compound(".hux", ".mumble"); 48 | 49 | std::cout << std::endl; 50 | 51 | check_complex(".foo ~ .bar", ".foo + .bar"); 52 | check_complex(".foo .bar", ".foo + .bar"); 53 | check_complex(".foo .bar", ".foo > .bar"); 54 | check_complex(".foo .bar > .hux", ".foo.a .bar.b > .hux"); 55 | check_complex(".foo ~ .bar .hux", ".foo.a + .bar.b > .hux"); 56 | check_complex(".foo", ".bar .foo"); 57 | check_complex(".foo", ".foo.a"); 58 | check_complex(".foo.bar", ".foo"); 59 | check_complex(".foo .bar .hux", ".bar .hux"); 60 | check_complex(".foo ~ .bar .hux.x", ".foo.a + .bar.b > .hux.y"); 61 | check_complex(".foo ~ .bar .hux", ".foo.a + .bar.b > .mumble"); 62 | check_complex(".foo + .bar", ".foo ~ .bar"); 63 | check_complex("a c e", "a b c d e"); 64 | check_complex("c a e", "a b c d e"); 65 | 66 | return 0; 67 | } 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/libsass/test/test_unification.cpp: -------------------------------------------------------------------------------- 1 | #include "../ast.hpp" 2 | #include "../context.hpp" 3 | #include "../parser.hpp" 4 | #include 5 | 6 | using namespace Sass; 7 | 8 | Context ctx = Context(Context::Data()); 9 | 10 | Compound_Selector* selector(std::string src) 11 | { return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_compound_selector(); } 12 | 13 | void unify(std::string lhs, std::string rhs) 14 | { 15 | Compound_Selector* unified = selector(lhs + ";")->unify_with(selector(rhs + ";"), ctx); 16 | std::cout << lhs << " UNIFIED WITH " << rhs << " =\t" << (unified ? unified->to_string() : "NOTHING") << std::endl; 17 | } 18 | 19 | int main() 20 | { 21 | unify(".foo", ".foo.bar"); 22 | unify("div:nth-of-type(odd)", "div:first-child"); 23 | unify("div", "span:whatever"); 24 | unify("div", "span"); 25 | unify("foo:bar::after", "foo:bar::first-letter"); 26 | unify(".foo#bar.hux", ".hux.foo#bar"); 27 | unify(".foo#bar.hux", ".hux.foo#baz"); 28 | unify("*:blah:fudge", "p:fudge:blah"); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/libsass/version.sh: -------------------------------------------------------------------------------- 1 | if test "x$LIBSASS_VERSION" = "x"; then 2 | LIBSASS_VERSION=`git describe --abbrev=4 --dirty --always --tags 2>/dev/null` 3 | fi 4 | if test "x$LIBSASS_VERSION" = "x"; then 5 | LIBSASS_VERSION=`cat VERSION 2>/dev/null` 6 | fi 7 | if test "x$LIBSASS_VERSION" = "x"; then 8 | LIBSASS_VERSION="[na]" 9 | fi 10 | echo $LIBSASS_VERSION 11 | -------------------------------------------------------------------------------- /src/libsass/win/libsass.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsass", "libsass.vcxproj", "{E4030474-AFC9-4CC6-BEB6-D846F631502B}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".SolutionItems", ".SolutionItems", "{33318C77-2391-4399-8118-C109155A4A75}" 9 | ProjectSection(SolutionItems) = preProject 10 | ..\.editorconfig = ..\.editorconfig 11 | ..\.gitattributes = ..\.gitattributes 12 | ..\.gitignore = ..\.gitignore 13 | ..\.travis.yml = ..\.travis.yml 14 | ..\appveyor.yml = ..\appveyor.yml 15 | ..\Readme.md = ..\Readme.md 16 | ..\res\resource.rc = ..\res\resource.rc 17 | EndProjectSection 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Win32 = Debug|Win32 22 | Debug|Win64 = Debug|Win64 23 | Release|Win32 = Release|Win32 24 | Release|Win64 = Release|Win64 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win32.ActiveCfg = Debug|Win32 28 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win32.Build.0 = Debug|Win32 29 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win64.ActiveCfg = Debug|x64 30 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win64.Build.0 = Debug|x64 31 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win32.ActiveCfg = Release|Win32 32 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win32.Build.0 = Release|Win32 33 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win64.ActiveCfg = Release|x64 34 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win64.Build.0 = Release|x64 35 | EndGlobalSection 36 | GlobalSection(SolutionProperties) = preSolution 37 | HideSolutionNode = FALSE 38 | EndGlobalSection 39 | EndGlobal 40 | -------------------------------------------------------------------------------- /src/libsass/win/libsass.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | ExplicitlyExcluded 3 | ExplicitlyExcluded 4 | ExplicitlyExcluded 5 | ExplicitlyExcluded 6 | ExplicitlyExcluded 7 | ExplicitlyExcluded 8 | ExplicitlyExcluded 9 | ExplicitlyExcluded -------------------------------------------------------------------------------- /src/sass_context_wrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "sass_context_wrapper.h" 2 | 3 | extern "C" { 4 | using namespace std; 5 | 6 | void compile_it(uv_work_t* req) { 7 | sass_context_wrapper* ctx_w = (sass_context_wrapper*)req->data; 8 | 9 | if (ctx_w->dctx) { 10 | compile_data(ctx_w->dctx); 11 | } 12 | else if (ctx_w->fctx) { 13 | compile_file(ctx_w->fctx); 14 | } 15 | } 16 | 17 | void compile_data(struct Sass_Data_Context* dctx) { 18 | sass_compile_data_context(dctx); 19 | } 20 | 21 | void compile_file(struct Sass_File_Context* fctx) { 22 | sass_compile_file_context(fctx); 23 | } 24 | 25 | sass_context_wrapper* sass_make_context_wrapper() { 26 | return (sass_context_wrapper*)calloc(1, sizeof(sass_context_wrapper)); 27 | } 28 | 29 | void sass_free_context_wrapper(sass_context_wrapper* ctx_w) { 30 | if (ctx_w->dctx) { 31 | sass_delete_data_context(ctx_w->dctx); 32 | } 33 | else if (ctx_w->fctx) { 34 | sass_delete_file_context(ctx_w->fctx); 35 | } 36 | if (ctx_w->async_resource) { 37 | delete ctx_w->async_resource; 38 | } 39 | 40 | delete ctx_w->error_callback; 41 | delete ctx_w->success_callback; 42 | 43 | ctx_w->result.Reset(); 44 | 45 | free(ctx_w->include_path); 46 | free(ctx_w->linefeed); 47 | free(ctx_w->out_file); 48 | free(ctx_w->source_map); 49 | free(ctx_w->source_map_root); 50 | free(ctx_w->indent); 51 | 52 | std::vector::iterator imp_it = ctx_w->importer_bridges.begin(); 53 | while (imp_it != ctx_w->importer_bridges.end()) { 54 | CustomImporterBridge* p = *imp_it; 55 | imp_it = ctx_w->importer_bridges.erase(imp_it); 56 | delete p; 57 | } 58 | std::vector::iterator func_it = ctx_w->function_bridges.begin(); 59 | while (func_it != ctx_w->function_bridges.end()) { 60 | CustomFunctionBridge* p = *func_it; 61 | func_it = ctx_w->function_bridges.erase(func_it); 62 | delete p; 63 | } 64 | 65 | free(ctx_w); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/sass_context_wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_CONTEXT_WRAPPER 2 | #define SASS_CONTEXT_WRAPPER 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "custom_function_bridge.h" 10 | #include "custom_importer_bridge.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | void compile_data(struct Sass_Data_Context* dctx); 17 | void compile_file(struct Sass_File_Context* fctx); 18 | void compile_it(uv_work_t* req); 19 | 20 | struct sass_context_wrapper { 21 | // binding related 22 | bool is_sync; 23 | void* cookie; 24 | char* file; 25 | char* include_path; 26 | char* out_file; 27 | char* source_map; 28 | char* source_map_root; 29 | char* linefeed; 30 | char* indent; 31 | 32 | // libsass related 33 | Sass_Data_Context* dctx; 34 | Sass_File_Context* fctx; 35 | 36 | // libuv related 37 | uv_async_t async; 38 | uv_work_t request; 39 | 40 | // v8 and nan related 41 | Nan::Persistent result; 42 | Nan::AsyncResource* async_resource; 43 | Nan::Callback* error_callback; 44 | Nan::Callback* success_callback; 45 | 46 | std::vector function_bridges; 47 | std::vector importer_bridges; 48 | }; 49 | 50 | struct sass_context_wrapper* sass_make_context_wrapper(void); 51 | void sass_free_context_wrapper(struct sass_context_wrapper*); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/sass_types/boolean.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "boolean.h" 3 | 4 | namespace SassTypes 5 | { 6 | Nan::Persistent Boolean::constructor; 7 | bool Boolean::constructor_locked = false; 8 | 9 | Boolean::Boolean(bool _value) { 10 | value = sass_make_boolean(_value); 11 | } 12 | 13 | Boolean& Boolean::get_singleton(bool v) { 14 | static Boolean instance_false(false), instance_true(true); 15 | return v ? instance_true : instance_false; 16 | } 17 | 18 | v8::Local Boolean::get_constructor() { 19 | Nan::EscapableHandleScope scope; 20 | v8::Local conslocal; 21 | if (constructor.IsEmpty()) { 22 | v8::Local tpl = Nan::New(New); 23 | 24 | tpl->SetClassName(Nan::New("SassBoolean").ToLocalChecked()); 25 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 26 | Nan::SetPrototypeTemplate(tpl, "getValue", Nan::New(GetValue)); 27 | 28 | conslocal = Nan::GetFunction(tpl).ToLocalChecked(); 29 | constructor.Reset(conslocal); 30 | 31 | get_singleton(false).js_object.Reset(Nan::NewInstance(conslocal).ToLocalChecked()); 32 | Nan::SetInternalFieldPointer(Nan::New(get_singleton(false).js_object), 0, &get_singleton(false)); 33 | Nan::Set(conslocal, Nan::New("FALSE").ToLocalChecked(), Nan::New(get_singleton(false).js_object)); 34 | 35 | get_singleton(true).js_object.Reset(Nan::NewInstance(conslocal).ToLocalChecked()); 36 | Nan::SetInternalFieldPointer(Nan::New(get_singleton(true).js_object), 0, &get_singleton(true)); 37 | Nan::Set(conslocal, Nan::New("TRUE").ToLocalChecked(), Nan::New(get_singleton(true).js_object)); 38 | 39 | constructor_locked = true; 40 | } else { 41 | conslocal = Nan::New(constructor); 42 | } 43 | 44 | return scope.Escape(conslocal); 45 | } 46 | 47 | v8::Local Boolean::get_js_object() { 48 | return Nan::New(this->js_object); 49 | } 50 | 51 | v8::Local Boolean::get_js_boolean() { 52 | return sass_boolean_get_value(this->value) ? Nan::True() : Nan::False(); 53 | } 54 | 55 | NAN_METHOD(Boolean::New) { 56 | if (info.IsConstructCall()) { 57 | if (constructor_locked) { 58 | return Nan::ThrowTypeError("Cannot instantiate SassBoolean"); 59 | } 60 | } 61 | else { 62 | if (info.Length() != 1 || !info[0]->IsBoolean()) { 63 | return Nan::ThrowTypeError("Expected one boolean argument"); 64 | } 65 | 66 | info.GetReturnValue().Set(get_singleton(Nan::To(info[0]).FromJust()).get_js_object()); 67 | } 68 | } 69 | 70 | NAN_METHOD(Boolean::GetValue) { 71 | info.GetReturnValue().Set(Boolean::Unwrap(info.This())->get_js_boolean()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/sass_types/boolean.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_BOOLEAN_H 2 | #define SASS_TYPES_BOOLEAN_H 3 | 4 | #include 5 | #include "value.h" 6 | #include "sass_value_wrapper.h" 7 | 8 | namespace SassTypes 9 | { 10 | class Boolean : public SassTypes::Value { 11 | public: 12 | static Boolean& get_singleton(bool); 13 | static v8::Local get_constructor(); 14 | 15 | v8::Local get_js_object(); 16 | 17 | static NAN_METHOD(New); 18 | static NAN_METHOD(GetValue); 19 | 20 | private: 21 | Boolean(bool); 22 | 23 | Nan::Persistent js_object; 24 | 25 | static Nan::Persistent constructor; 26 | static bool constructor_locked; 27 | v8::Local get_js_boolean(); 28 | }; 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/sass_types/color.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_COLOR_H 2 | #define SASS_TYPES_COLOR_H 3 | 4 | #include 5 | #include "sass_value_wrapper.h" 6 | 7 | #if defined(__GNUC__) && __GNUC__ >= 7 8 | #define NODE_SASS_FALLTHROUGH __attribute__ ((fallthrough)) 9 | #else 10 | #define NODE_SASS_FALLTHROUGH 11 | #endif 12 | 13 | namespace SassTypes 14 | { 15 | class Color : public SassValueWrapper { 16 | public: 17 | Color(Sass_Value*); 18 | static char const* get_constructor_name() { return "SassColor"; } 19 | static Sass_Value* construct(const std::vector>, Sass_Value **); 20 | 21 | static void initPrototype(v8::Local); 22 | 23 | static NAN_METHOD(GetR); 24 | static NAN_METHOD(GetG); 25 | static NAN_METHOD(GetB); 26 | static NAN_METHOD(GetA); 27 | static NAN_METHOD(SetR); 28 | static NAN_METHOD(SetG); 29 | static NAN_METHOD(SetB); 30 | static NAN_METHOD(SetA); 31 | }; 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/sass_types/error.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "error.h" 3 | #include "../create_string.h" 4 | 5 | namespace SassTypes 6 | { 7 | Error::Error(Sass_Value* v) : SassValueWrapper(v) {} 8 | 9 | Sass_Value* Error::construct(const std::vector> raw_val, Sass_Value **out) { 10 | char const* value = ""; 11 | 12 | if (raw_val.size() >= 1) { 13 | if (!raw_val[0]->IsString()) { 14 | return fail("Argument should be a string.", out); 15 | } 16 | 17 | value = create_string(raw_val[0]); 18 | } 19 | 20 | return *out = sass_make_error(value); 21 | } 22 | 23 | void Error::initPrototype(v8::Local) {} 24 | } 25 | -------------------------------------------------------------------------------- /src/sass_types/error.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_ERROR_H 2 | #define SASS_TYPES_ERROR_H 3 | 4 | #include 5 | #include "sass_value_wrapper.h" 6 | 7 | namespace SassTypes 8 | { 9 | class Error : public SassValueWrapper { 10 | public: 11 | Error(Sass_Value*); 12 | static char const* get_constructor_name() { return "SassError"; } 13 | static Sass_Value* construct(const std::vector>, Sass_Value **); 14 | 15 | static void initPrototype(v8::Local); 16 | }; 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/sass_types/factory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "factory.h" 3 | #include "value.h" 4 | #include "number.h" 5 | #include "string.h" 6 | #include "color.h" 7 | #include "boolean.h" 8 | #include "list.h" 9 | #include "map.h" 10 | #include "null.h" 11 | #include "error.h" 12 | 13 | namespace SassTypes 14 | { 15 | SassTypes::Value* Factory::create(Sass_Value* v) { 16 | switch (sass_value_get_tag(v)) { 17 | case SASS_NUMBER: 18 | return new Number(v); 19 | 20 | case SASS_STRING: 21 | return new String(v); 22 | 23 | case SASS_COLOR: 24 | return new Color(v); 25 | 26 | case SASS_BOOLEAN: 27 | return &Boolean::get_singleton(sass_boolean_get_value(v)); 28 | 29 | case SASS_LIST: 30 | return new List(v); 31 | 32 | case SASS_MAP: 33 | return new Map(v); 34 | 35 | case SASS_NULL: 36 | return &Null::get_singleton(); 37 | 38 | case SASS_ERROR: 39 | return new Error(v); 40 | 41 | default: 42 | const char *msg = "Unknown type encountered."; 43 | Nan::ThrowTypeError(msg); 44 | return new Error(sass_make_error(msg)); 45 | } 46 | } 47 | 48 | NAN_MODULE_INIT(Factory::initExports) { 49 | Nan::HandleScope scope; 50 | v8::Local types = Nan::New(); 51 | 52 | Nan::Set(types, Nan::New("Number").ToLocalChecked(), Number::get_constructor()); 53 | Nan::Set(types, Nan::New("String").ToLocalChecked(), String::get_constructor()); 54 | Nan::Set(types, Nan::New("Color").ToLocalChecked(), Color::get_constructor()); 55 | Nan::Set(types, Nan::New("Boolean").ToLocalChecked(), Boolean::get_constructor()); 56 | Nan::Set(types, Nan::New("List").ToLocalChecked(), List::get_constructor()); 57 | Nan::Set(types, Nan::New("Map").ToLocalChecked(), Map::get_constructor()); 58 | Nan::Set(types, Nan::New("Null").ToLocalChecked(), Null::get_constructor()); 59 | Nan::Set(types, Nan::New("Error").ToLocalChecked(), Error::get_constructor()); 60 | Nan::Set(target, Nan::New("types").ToLocalChecked(), types); 61 | } 62 | 63 | Value* Factory::unwrap(v8::Local obj) { 64 | if (obj->IsObject()) { 65 | v8::Local v8_obj = obj.As(); 66 | if (v8_obj->InternalFieldCount() == 1) { 67 | return SassTypes::Value::Unwrap(v8_obj); 68 | } 69 | } 70 | return NULL; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/sass_types/factory.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_FACTORY_H 2 | #define SASS_TYPES_FACTORY_H 3 | 4 | #include 5 | #include 6 | #include "value.h" 7 | 8 | namespace SassTypes 9 | { 10 | // This is the guru that knows everything about instantiating the right subclass of SassTypes::Value 11 | // to wrap a given Sass_Value object. 12 | class Factory { 13 | public: 14 | static NAN_MODULE_INIT(initExports); 15 | static Value* create(Sass_Value*); 16 | static Value* unwrap(v8::Local); 17 | }; 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/sass_types/list.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_LIST_H 2 | #define SASS_TYPES_LIST_H 3 | 4 | #include 5 | #include "sass_value_wrapper.h" 6 | 7 | namespace SassTypes 8 | { 9 | class List : public SassValueWrapper { 10 | public: 11 | List(Sass_Value*); 12 | static char const* get_constructor_name() { return "SassList"; } 13 | static Sass_Value* construct(const std::vector>, Sass_Value **); 14 | 15 | static void initPrototype(v8::Local); 16 | 17 | static NAN_METHOD(GetValue); 18 | static NAN_METHOD(SetValue); 19 | static NAN_METHOD(GetSeparator); 20 | static NAN_METHOD(SetSeparator); 21 | static NAN_METHOD(GetLength); 22 | }; 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/sass_types/map.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_MAP_H 2 | #define SASS_TYPES_MAP_H 3 | 4 | #include 5 | #include "sass_value_wrapper.h" 6 | 7 | namespace SassTypes 8 | { 9 | class Map : public SassValueWrapper { 10 | public: 11 | Map(Sass_Value*); 12 | static char const* get_constructor_name() { return "SassMap"; } 13 | static Sass_Value* construct(const std::vector>, Sass_Value **); 14 | 15 | static void initPrototype(v8::Local); 16 | 17 | static NAN_METHOD(GetValue); 18 | static NAN_METHOD(SetValue); 19 | static NAN_METHOD(GetKey); 20 | static NAN_METHOD(SetKey); 21 | static NAN_METHOD(GetLength); 22 | }; 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/sass_types/null.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "null.h" 3 | 4 | namespace SassTypes 5 | { 6 | Nan::Persistent Null::constructor; 7 | bool Null::constructor_locked = false; 8 | 9 | Null::Null() { 10 | value = sass_make_null(); 11 | } 12 | 13 | Null& Null::get_singleton() { 14 | static Null singleton_instance; 15 | return singleton_instance; 16 | } 17 | 18 | v8::Local Null::get_constructor() { 19 | Nan::EscapableHandleScope scope; 20 | v8::Local conslocal; 21 | if (constructor.IsEmpty()) { 22 | v8::Local tpl = Nan::New(New); 23 | 24 | tpl->SetClassName(Nan::New("SassNull").ToLocalChecked()); 25 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 26 | 27 | conslocal = Nan::GetFunction(tpl).ToLocalChecked(); 28 | constructor.Reset(conslocal); 29 | 30 | get_singleton().js_object.Reset(Nan::NewInstance(conslocal).ToLocalChecked()); 31 | Nan::SetInternalFieldPointer(Nan::New(get_singleton().js_object), 0, &get_singleton()); 32 | Nan::Set(conslocal, Nan::New("NULL").ToLocalChecked(), Nan::New(get_singleton().js_object)); 33 | 34 | constructor_locked = true; 35 | } else { 36 | conslocal = Nan::New(constructor); 37 | } 38 | 39 | return scope.Escape(conslocal); 40 | } 41 | 42 | v8::Local Null::get_js_object() { 43 | return Nan::New(this->js_object); 44 | } 45 | 46 | NAN_METHOD(Null::New) { 47 | 48 | if (info.IsConstructCall()) { 49 | if (constructor_locked) { 50 | return Nan::ThrowTypeError("Cannot instantiate SassNull"); 51 | } 52 | } 53 | else { 54 | info.GetReturnValue().Set(get_singleton().get_js_object()); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/sass_types/null.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_NULL_H 2 | #define SASS_TYPES_NULL_H 3 | 4 | #include 5 | #include "value.h" 6 | 7 | namespace SassTypes 8 | { 9 | class Null : public SassTypes::Value { 10 | public: 11 | static Null& get_singleton(); 12 | static v8::Local get_constructor(); 13 | 14 | Sass_Value* get_sass_value(); 15 | v8::Local get_js_object(); 16 | 17 | static NAN_METHOD(New); 18 | 19 | private: 20 | Null(); 21 | 22 | Nan::Persistent js_object; 23 | 24 | static Nan::Persistent constructor; 25 | static bool constructor_locked; 26 | }; 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/sass_types/number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "number.h" 3 | #include "../create_string.h" 4 | 5 | namespace SassTypes 6 | { 7 | Number::Number(Sass_Value* v) : SassValueWrapper(v) {} 8 | 9 | Sass_Value* Number::construct(const std::vector> raw_val, Sass_Value **out) { 10 | double value = 0; 11 | char const* unit = ""; 12 | 13 | if (raw_val.size() >= 1) { 14 | if (!raw_val[0]->IsNumber()) { 15 | return fail("First argument should be a number.", out); 16 | } 17 | 18 | value = Nan::To(raw_val[0]).FromJust(); 19 | 20 | if (raw_val.size() >= 2) { 21 | if (!raw_val[1]->IsString()) { 22 | return fail("Second argument should be a string.", out); 23 | } 24 | 25 | unit = create_string(raw_val[1]); 26 | *out = sass_make_number(value, unit); 27 | delete unit; 28 | return *out; 29 | 30 | } 31 | } 32 | 33 | return *out = sass_make_number(value, unit); 34 | } 35 | 36 | void Number::initPrototype(v8::Local proto) { 37 | Nan::SetPrototypeMethod(proto, "getValue", GetValue); 38 | Nan::SetPrototypeMethod(proto, "getUnit", GetUnit); 39 | Nan::SetPrototypeMethod(proto, "setValue", SetValue); 40 | Nan::SetPrototypeMethod(proto, "setUnit", SetUnit); 41 | } 42 | 43 | NAN_METHOD(Number::GetValue) { 44 | info.GetReturnValue().Set(Nan::New(sass_number_get_value(Number::Unwrap(info.This())->value))); 45 | } 46 | 47 | NAN_METHOD(Number::GetUnit) { 48 | info.GetReturnValue().Set(Nan::New(sass_number_get_unit(Number::Unwrap(info.This())->value)).ToLocalChecked()); 49 | } 50 | 51 | NAN_METHOD(Number::SetValue) { 52 | 53 | if (info.Length() != 1) { 54 | return Nan::ThrowTypeError("Expected just one argument"); 55 | } 56 | 57 | if (!info[0]->IsNumber()) { 58 | return Nan::ThrowTypeError("Supplied value should be a number"); 59 | } 60 | 61 | sass_number_set_value(Number::Unwrap(info.This())->value, Nan::To(info[0]).FromJust()); 62 | } 63 | 64 | NAN_METHOD(Number::SetUnit) { 65 | if (info.Length() != 1) { 66 | return Nan::ThrowTypeError("Expected just one argument"); 67 | } 68 | 69 | if (!info[0]->IsString()) { 70 | return Nan::ThrowTypeError("Supplied value should be a string"); 71 | } 72 | 73 | sass_number_set_unit(Number::Unwrap(info.This())->value, create_string(info[0])); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/sass_types/number.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_NUMBER_H 2 | #define SASS_TYPES_NUMBER_H 3 | 4 | #include 5 | #include "sass_value_wrapper.h" 6 | 7 | namespace SassTypes 8 | { 9 | 10 | class Number : public SassValueWrapper { 11 | public: 12 | Number(Sass_Value*); 13 | static char const* get_constructor_name() { return "SassNumber"; } 14 | static Sass_Value* construct(const std::vector>, Sass_Value **out); 15 | 16 | static void initPrototype(v8::Local); 17 | 18 | static NAN_METHOD(GetValue); 19 | static NAN_METHOD(GetUnit); 20 | static NAN_METHOD(SetValue); 21 | static NAN_METHOD(SetUnit); 22 | }; 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/sass_types/string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "string.h" 3 | #include "../create_string.h" 4 | 5 | namespace SassTypes 6 | { 7 | String::String(Sass_Value* v) : SassValueWrapper(v) {} 8 | 9 | Sass_Value* String::construct(const std::vector> raw_val, Sass_Value **out) { 10 | char const* value = ""; 11 | 12 | if (raw_val.size() >= 1) { 13 | if (!raw_val[0]->IsString()) { 14 | return fail("Argument should be a string.", out); 15 | } 16 | 17 | value = create_string(raw_val[0]); 18 | *out = sass_make_string(value); 19 | delete value; 20 | return *out; 21 | 22 | } else { 23 | return *out = sass_make_string(value); 24 | } 25 | 26 | } 27 | 28 | void String::initPrototype(v8::Local proto) { 29 | Nan::SetPrototypeMethod(proto, "getValue", GetValue); 30 | Nan::SetPrototypeMethod(proto, "setValue", SetValue); 31 | } 32 | 33 | NAN_METHOD(String::GetValue) { 34 | info.GetReturnValue().Set(Nan::New(sass_string_get_value(String::Unwrap(info.This())->value)).ToLocalChecked()); 35 | } 36 | 37 | NAN_METHOD(String::SetValue) { 38 | if (info.Length() != 1) { 39 | return Nan::ThrowTypeError("Expected just one argument"); 40 | } 41 | 42 | if (!info[0]->IsString()) { 43 | return Nan::ThrowTypeError("Supplied value should be a string"); 44 | } 45 | 46 | sass_string_set_value(String::Unwrap(info.This())->value, create_string(info[0])); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/sass_types/string.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_STRING_H 2 | #define SASS_TYPES_STRING_H 3 | 4 | #include 5 | #include "sass_value_wrapper.h" 6 | 7 | namespace SassTypes 8 | { 9 | class String : public SassValueWrapper { 10 | public: 11 | String(Sass_Value*); 12 | static char const* get_constructor_name() { return "SassString"; } 13 | static Sass_Value* construct(const std::vector>, Sass_Value **); 14 | 15 | static void initPrototype(v8::Local); 16 | 17 | static NAN_METHOD(GetValue); 18 | static NAN_METHOD(SetValue); 19 | }; 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/sass_types/value.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TYPES_VALUE_H 2 | #define SASS_TYPES_VALUE_H 3 | 4 | #include 5 | #include 6 | 7 | namespace SassTypes 8 | { 9 | // This is the interface that all sass values must comply with 10 | class Value : public Nan::ObjectWrap { 11 | 12 | public: 13 | virtual v8::Local get_js_object() =0; 14 | 15 | Value() { 16 | 17 | } 18 | 19 | Sass_Value* get_sass_value() { 20 | return sass_clone_value(this->value); 21 | } 22 | 23 | protected: 24 | 25 | Sass_Value* value; 26 | 27 | Value(Sass_Value* v) { 28 | this->value = sass_clone_value(v); 29 | } 30 | 31 | ~Value() { 32 | sass_delete_value(this->value); 33 | } 34 | 35 | static Sass_Value* fail(const char *reason, Sass_Value **out) { 36 | *out = sass_make_error(reason); 37 | return NULL; 38 | } 39 | }; 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /test/errors.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert').strict, 2 | path = require('path'), 3 | errors = require('../lib/errors'); 4 | 5 | describe('binary errors', function() { 6 | 7 | function getCurrentPlatform() { 8 | if (process.platform === 'win32') { 9 | return 'Windows'; 10 | } else if (process.platform === 'darwin') { 11 | return 'OS X'; 12 | } 13 | return ''; 14 | } 15 | 16 | function getCurrentArchitecture() { 17 | if (process.arch === 'x86' || process.arch === 'ia32') { 18 | return '32-bit'; 19 | } else if (process.arch === 'x64') { 20 | return '64-bit'; 21 | } 22 | return ''; 23 | } 24 | 25 | function getCurrentEnvironment() { 26 | return getCurrentPlatform() + ' ' + getCurrentArchitecture(); 27 | } 28 | 29 | describe('for an unsupported environment', function() { 30 | it('identifies the current environment', function() { 31 | var message = errors.unsupportedEnvironment(); 32 | assert.ok(message.indexOf(getCurrentEnvironment()) !== -1); 33 | }); 34 | 35 | it('links to supported environment documentation', function() { 36 | var message = errors.unsupportedEnvironment(); 37 | assert.ok(message.indexOf('https://github.com/sass/node-sass/releases/tag/v') !== -1); 38 | }); 39 | }); 40 | 41 | describe('for an missing binary', function() { 42 | it('identifies the current environment', function() { 43 | var message = errors.missingBinary(); 44 | assert.ok(message.indexOf(getCurrentEnvironment()) !== -1); 45 | }); 46 | 47 | it('documents the expected binary location', function() { 48 | var message = errors.missingBinary(); 49 | assert.ok(message.indexOf(path.sep + 'vendor' + path.sep) !== -1); 50 | }); 51 | }); 52 | 53 | }); 54 | -------------------------------------------------------------------------------- /test/fixtures/compressed/expected.css: -------------------------------------------------------------------------------- 1 | #navbar{width:80%;height:23px}#navbar ul{list-style-type:none}#navbar li{float:left}#navbar li a{font-weight:bold} 2 | -------------------------------------------------------------------------------- /test/fixtures/compressed/index.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/custom-functions/setter-expected.css: -------------------------------------------------------------------------------- 1 | div { 2 | width: 42rem; 3 | height: 84px; } 4 | -------------------------------------------------------------------------------- /test/fixtures/custom-functions/setter.scss: -------------------------------------------------------------------------------- 1 | div { width: foo(42px); height: bar(42px); } 2 | -------------------------------------------------------------------------------- /test/fixtures/custom-functions/string-conversion-expected.css: -------------------------------------------------------------------------------- 1 | div { 2 | color: "barbar"; } 3 | -------------------------------------------------------------------------------- /test/fixtures/custom-functions/string-conversion.scss: -------------------------------------------------------------------------------- 1 | div { color: foo("bar"); } 2 | -------------------------------------------------------------------------------- /test/fixtures/cwd-include-path/expected.css: -------------------------------------------------------------------------------- 1 | .outside { 2 | color: red; } 3 | -------------------------------------------------------------------------------- /test/fixtures/cwd-include-path/outside.scss: -------------------------------------------------------------------------------- 1 | .outside { 2 | color: red; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/cwd-include-path/root/index.scss: -------------------------------------------------------------------------------- 1 | @import 'outside'; 2 | -------------------------------------------------------------------------------- /test/fixtures/depth-first/_common.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | @import "struct"; 3 | 4 | .myvars { 5 | content: quote($import_counter); 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/depth-first/_struct.scss: -------------------------------------------------------------------------------- 1 | .common-struct { 2 | content: "common-struct"; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/depth-first/_vars.scss: -------------------------------------------------------------------------------- 1 | $import_counter: $import_counter + 1; 2 | 3 | .common-vars { 4 | content: "common-vars"; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/depth-first/a.scss: -------------------------------------------------------------------------------- 1 | @import "_common"; 2 | @import "a1"; 3 | 4 | .a2 { 5 | content: "a2"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /test/fixtures/depth-first/a1.scss: -------------------------------------------------------------------------------- 1 | .a1 { 2 | content: "a1"; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/depth-first/b.scss: -------------------------------------------------------------------------------- 1 | @import "b1"; 2 | 3 | .b2 { 4 | content: "b2"; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/depth-first/b1.scss: -------------------------------------------------------------------------------- 1 | .b1 { 2 | content: "b1"; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/depth-first/expected.css: -------------------------------------------------------------------------------- 1 | .common-vars { 2 | content: "common-vars"; } 3 | 4 | .common-struct { 5 | content: "common-struct"; } 6 | 7 | .myvars { 8 | content: "1"; } 9 | 10 | .a1 { 11 | content: "a1"; } 12 | 13 | .a2 { 14 | content: "a2"; } 15 | 16 | .common-vars { 17 | content: "common-vars"; } 18 | 19 | .common-struct { 20 | content: "common-struct"; } 21 | 22 | .myvars { 23 | content: "2"; } 24 | 25 | .b1 { 26 | content: "b1"; } 27 | 28 | .b2 { 29 | content: "b2"; } 30 | 31 | #the-last { 32 | content: "LAST"; } -------------------------------------------------------------------------------- /test/fixtures/depth-first/index.scss: -------------------------------------------------------------------------------- 1 | $import_counter: 0; 2 | @import "a"; 3 | @import "common"; 4 | @import "b"; 5 | 6 | #the-last { 7 | content: "LAST"; 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_arrays_of_importers.js: -------------------------------------------------------------------------------- 1 | var sass = require('../../..'); 2 | 3 | module.exports = [ 4 | function() { 5 | return sass.NULL; 6 | }, 7 | function() { 8 | return { 9 | contents: 'div {color: yellow;}' 10 | }; 11 | } 12 | ]; 13 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_functions_setter.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'foo($a)': function(size) { 3 | size.setUnit('rem'); 4 | return size; 5 | }, 6 | 'bar($a)': function(size) { 7 | size.setValue(size.getValue() * 2); 8 | return size; 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_functions_string_conversion.js: -------------------------------------------------------------------------------- 1 | var sass = require('../../..'); 2 | 3 | module.exports = { 4 | 'foo($a)': function(str) { 5 | str = str.getValue().replace(/['"]/g, ''); 6 | return new sass.types.String('"' + str + str + '"'); 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_importer_data.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | contents: 'div {color: yellow;}' 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_importer_data_cb.js: -------------------------------------------------------------------------------- 1 | module.exports = function(file, prev, done) { 2 | done({ 3 | contents: 'div {color: yellow;}' 4 | }); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_importer_error.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return new Error('doesn\'t exist!'); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_importer_file.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = function(file) { 4 | return { 5 | file: path.resolve(path.join(process.cwd(), 'test/fixtures/include-files/', file + (path.extname(file) ? '' : '.scss'))) 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_importer_file_and_data.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | file: '/some/random/path/file.scss', 4 | contents: 'div {color: yellow;}' 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_importer_file_and_data_cb.js: -------------------------------------------------------------------------------- 1 | module.exports = function(file, prev, done) { 2 | done({ 3 | file: '/some/random/path/file.scss', 4 | contents: 'div {color: yellow;}' 5 | }); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/extras/my_custom_importer_file_cb.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = function(file, /* jshint unused:false */ prev, done) { 4 | done({ 5 | file: path.resolve(path.join(process.cwd(), 'test/fixtures/include-files/', file + (path.extname(file) ? '' : '.scss'))) 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/follow/foo/bar/index.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/include-files/bar.scss: -------------------------------------------------------------------------------- 1 | /* bar.scss */ 2 | -------------------------------------------------------------------------------- /test/fixtures/include-files/chained-imports-with-custom-importer.scss: -------------------------------------------------------------------------------- 1 | @import "file-not-processed-by-loader", "file-processed-by-loader"; 2 | -------------------------------------------------------------------------------- /test/fixtures/include-files/expected-data-importer.css: -------------------------------------------------------------------------------- 1 | div { 2 | color: yellow; } 3 | 4 | div { 5 | color: yellow; } 6 | -------------------------------------------------------------------------------- /test/fixtures/include-files/expected-file-importer.css: -------------------------------------------------------------------------------- 1 | /* foo.scss */ 2 | /* bar.scss */ 3 | -------------------------------------------------------------------------------- /test/fixtures/include-files/expected-importer.css: -------------------------------------------------------------------------------- 1 | div { 2 | color: yellow; } 3 | 4 | div { 5 | color: yellow; } 6 | -------------------------------------------------------------------------------- /test/fixtures/include-files/file-not-processed-by-loader.scss: -------------------------------------------------------------------------------- 1 | $variable-defined-by-file-not-processed-by-loader: 'red'; 2 | -------------------------------------------------------------------------------- /test/fixtures/include-files/file-processed-by-loader.scss: -------------------------------------------------------------------------------- 1 | body { 2 | color: $variable-defined-by-file-not-processed-by-loader; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/include-files/foo.scss: -------------------------------------------------------------------------------- 1 | /* foo.scss */ 2 | -------------------------------------------------------------------------------- /test/fixtures/include-files/index.scss: -------------------------------------------------------------------------------- 1 | @import 'foo'; 2 | @import 'bar'; 3 | -------------------------------------------------------------------------------- /test/fixtures/include-path/expected.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: red; 3 | color: #0000fe; } 4 | -------------------------------------------------------------------------------- /test/fixtures/include-path/functions/colorBlue.scss: -------------------------------------------------------------------------------- 1 | @function colorBlue() { 2 | @return #0000fe; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/include-path/index.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'colorBlue'; 3 | 4 | body { 5 | background: $color; 6 | color: colorBlue(); 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/include-path/lib/vars.scss: -------------------------------------------------------------------------------- 1 | $color: red; 2 | -------------------------------------------------------------------------------- /test/fixtures/indent/expected.css: -------------------------------------------------------------------------------- 1 | foo + bar { 2 | color: red; } 3 | -------------------------------------------------------------------------------- /test/fixtures/indent/index.sass: -------------------------------------------------------------------------------- 1 | foo 2 | + bar 3 | color: red 4 | -------------------------------------------------------------------------------- /test/fixtures/input-directory/sass/_skipped.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/input-directory/sass/nested/three.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/input-directory/sass/one.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/input-directory/sass/two.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/invalid/index.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: $green; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/output-directory/index.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/precision/expected.css: -------------------------------------------------------------------------------- 1 | .foo { 2 | margin: 1.23456789 px; } 3 | -------------------------------------------------------------------------------- /test/fixtures/precision/index.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | margin: 1.23456789 px; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/sass-path/expected-orange.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: orange; } 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/sass-path/expected-red.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: red; } 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/sass-path/index.scss: -------------------------------------------------------------------------------- 1 | @import 'colors'; 2 | 3 | body { 4 | background: $color; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/sass-path/orange/colors.scss: -------------------------------------------------------------------------------- 1 | $color: orange; 2 | -------------------------------------------------------------------------------- /test/fixtures/sass-path/red/colors.scss: -------------------------------------------------------------------------------- 1 | $color: red; 2 | -------------------------------------------------------------------------------- /test/fixtures/simple/expected.css: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; } 4 | 5 | #navbar ul { 6 | list-style-type: none; } 7 | 8 | #navbar li { 9 | float: left; } 10 | #navbar li a { 11 | font-weight: bold; } 12 | -------------------------------------------------------------------------------- /test/fixtures/simple/index.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/source-comments/expected.css: -------------------------------------------------------------------------------- 1 | /* line 1, stdin */ 2 | #navbar { 3 | width: 80%; 4 | height: 23px; } 5 | 6 | /* line 6, stdin */ 7 | #navbar ul { 8 | list-style-type: none; } 9 | 10 | /* line 10, stdin */ 11 | #navbar li { 12 | float: left; } 13 | /* line 13, stdin */ 14 | #navbar li a { 15 | font-weight: bold; } 16 | -------------------------------------------------------------------------------- /test/fixtures/source-comments/index.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/source-map-embed/expected.css: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; } 4 | 5 | #navbar ul { 6 | list-style-type: none; } 7 | 8 | #navbar li { 9 | float: left; } 10 | #navbar li a { 11 | font-weight: bold; } 12 | 13 | /*# sourceMappingURL=data:application/json;base64,ewoJInZlcnNpb24iOiAzLAoJImZpbGUiOiAidGVzdC9maXh0dXJlcy9zb3VyY2UtbWFwLWVtYmVkL2luZGV4LmNzcyIsCgkic291cmNlcyI6IFsKCQkidGVzdC9maXh0dXJlcy9zb3VyY2UtbWFwLWVtYmVkL2luZGV4LnNjc3MiCgldLAoJIm5hbWVzIjogW10sCgkibWFwcGluZ3MiOiAiQUFBQSxBQUFBLE9BQU8sQ0FBQztFQUNOLEtBQUssRUFBRSxHQUFHO0VBQ1YsTUFBTSxFQUFFLElBQUksR0FDYjs7QUFFRCxBQUFBLE9BQU8sQ0FBQyxFQUFFLENBQUM7RUFDVCxlQUFlLEVBQUUsSUFBSSxHQUN0Qjs7QUFFRCxBQUFBLE9BQU8sQ0FBQyxFQUFFLENBQUM7RUFDVCxLQUFLLEVBQUUsSUFBSSxHQUtaO0VBTkQsQUFHRSxPQUhLLENBQUMsRUFBRSxDQUdSLENBQUMsQ0FBQztJQUNBLFdBQVcsRUFBRSxJQUFJLEdBQ2xCIgp9 */ 14 | -------------------------------------------------------------------------------- /test/fixtures/source-map-embed/index.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/source-map/expected.css: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; } 4 | 5 | #navbar ul { 6 | list-style-type: none; } 7 | 8 | #navbar li { 9 | float: left; } 10 | #navbar li a { 11 | font-weight: bold; } 12 | 13 | /*# sourceMappingURL=index.map */ 14 | -------------------------------------------------------------------------------- /test/fixtures/source-map/expected.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "index.css", 4 | "sources": [ 5 | "index.scss" 6 | ], 7 | "names": [], 8 | "mappings": "AAAA,AAAA,OAAO,CAAC;EACN,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,IAAI,GACb;;AAED,AAAA,OAAO,CAAC,EAAE,CAAC;EACT,eAAe,EAAE,IAAI,GACtB;;AAED,AAAA,OAAO,CAAC,EAAE,CAAC;EACT,KAAK,EAAE,IAAI,GAKZ;EAND,AAGE,OAHK,CAAC,EAAE,CAGR,CAAC,CAAC;IACA,WAAW,EAAE,IAAI,GAClB" 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/source-map/index.scss: -------------------------------------------------------------------------------- 1 | #navbar { 2 | width: 80%; 3 | height: 23px; 4 | } 5 | 6 | #navbar ul { 7 | list-style-type: none; 8 | } 9 | 10 | #navbar li { 11 | float: left; 12 | 13 | a { 14 | font-weight: bold; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/watcher/main/one.scss: -------------------------------------------------------------------------------- 1 | @import "partials/one"; 2 | 3 | .one { 4 | color: red; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/watcher/main/partials/_one.scss: -------------------------------------------------------------------------------- 1 | @import "partials/three"; 2 | 3 | .one { 4 | color: darkred; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/watcher/main/partials/_three.scss: -------------------------------------------------------------------------------- 1 | .three { 2 | color: darkgreen; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/watcher/main/partials/_two.scss: -------------------------------------------------------------------------------- 1 | @import "partials/three"; 2 | 3 | .two { 4 | color: darkblue; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/watcher/main/three.scss: -------------------------------------------------------------------------------- 1 | .three { 2 | color: green; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/watcher/main/two.scss: -------------------------------------------------------------------------------- 1 | .two { 2 | color: blue; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/watcher/sibling/partials/_three.scss: -------------------------------------------------------------------------------- 1 | .three { 2 | color: darkgreen; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/watcher/sibling/three.scss: -------------------------------------------------------------------------------- 1 | @import "partials/three"; 2 | 3 | .three { 4 | color: green; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/watching-dir-01/index.scss: -------------------------------------------------------------------------------- 1 | a {color:green;} 2 | -------------------------------------------------------------------------------- /test/fixtures/watching-dir-02/foo.scss: -------------------------------------------------------------------------------- 1 | body{background:white} 2 | -------------------------------------------------------------------------------- /test/fixtures/watching-dir-02/index.scss: -------------------------------------------------------------------------------- 1 | @import './foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/watching/bar.sass: -------------------------------------------------------------------------------- 1 | body 2 | background: white 3 | -------------------------------------------------------------------------------- /test/fixtures/watching/index.sass: -------------------------------------------------------------------------------- 1 | @import "bar.sass"; 2 | -------------------------------------------------------------------------------- /test/fixtures/watching/index.scss: -------------------------------------------------------------------------------- 1 | @import './white'; 2 | -------------------------------------------------------------------------------- /test/fixtures/watching/white.scss: -------------------------------------------------------------------------------- 1 | body{background:white} 2 | -------------------------------------------------------------------------------- /test/scripts/util/proxy.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert').strict, 2 | proxy = require('../../../scripts/util/proxy'); 3 | 4 | describe('proxy', function() { 5 | var oldEnvironment; 6 | 7 | beforeEach(function() { 8 | oldEnvironment = process.env; 9 | }); 10 | 11 | afterEach(function() { 12 | process.env = oldEnvironment; 13 | }); 14 | 15 | describe('without an npm proxy config', function() { 16 | delete process.env.npm_config_https_proxy; 17 | delete process.env.npm_config_proxy; 18 | delete process.env.npm_config_http_proxy; 19 | 20 | it('should return an empty string', function() { 21 | assert.strictEqual('', proxy()); 22 | }); 23 | 24 | it('should ignore system proxy environment variables', function() { 25 | process.env.HTTPS_PROXY = 'http://https_proxy.com'; 26 | process.env.PROXY = 'http://proxy.com'; 27 | process.env.HTTP_PROXY = 'http://http_proxy.com'; 28 | 29 | assert.strictEqual('', proxy()); 30 | }); 31 | }); 32 | 33 | describe('with an npm proxy config', function() { 34 | beforeEach(function() { 35 | process.env.npm_config_https_proxy = 'http://https_proxy.com'; 36 | process.env.npm_config_proxy = 'http://proxy.com'; 37 | process.env.npm_config_http_proxy = 'http://http_proxy.com'; 38 | }); 39 | 40 | describe('https_proxy', function() { 41 | it('should have the highest precedence', function() { 42 | assert.strictEqual(process.env.npm_config_https_proxy, proxy()); 43 | }); 44 | }); 45 | 46 | describe('proxy', function() { 47 | it('should have the higher precedence than https_proxy', function() { 48 | assert.strictEqual(process.env.npm_config_https_proxy, proxy()); 49 | delete process.env.npm_config_https_proxy; 50 | 51 | assert.strictEqual(process.env.npm_config_proxy, proxy()); 52 | }); 53 | 54 | it('should have the lower precedence than http_proxy', function() { 55 | delete process.env.npm_config_https_proxy; 56 | 57 | assert.strictEqual(process.env.npm_config_proxy, proxy()); 58 | delete process.env.npm_config_proxy; 59 | 60 | assert.strictEqual(process.env.npm_config_http_proxy, proxy()); 61 | }); 62 | }); 63 | 64 | describe('http_proxy', function() { 65 | it('should have the lowest precedence', function() { 66 | assert.strictEqual(process.env.npm_config_https_proxy, proxy()); 67 | delete process.env.npm_config_https_proxy; 68 | 69 | assert.strictEqual(process.env.npm_config_proxy, proxy()); 70 | delete process.env.npm_config_proxy; 71 | 72 | assert.strictEqual(process.env.npm_config_http_proxy, proxy()); 73 | }); 74 | }); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /test/useragent.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert').strict, 2 | pkg = require('../package.json'), 3 | ua = require('../scripts/util/useragent'); 4 | 5 | describe('util', function() { 6 | describe('useragent', function() { 7 | it('should look as we expect', function() { 8 | var reNode = 'node/' + process.version; 9 | var reSass = 'node-sass-installer/' + pkg.version; 10 | var reUA = new RegExp('^' + reNode + ' ' + reSass + '$'); 11 | 12 | assert.ok(reUA.test(ua())); 13 | }); 14 | }); 15 | }); 16 | --------------------------------------------------------------------------------